北邮OJ 980. 16校赛-R_clover's Challenge

来源:互联网 发布:军阀割据知乎 编辑:程序博客网 时间:2024/05/18 23:55

题目描述

    R_clover wants to challenge Mengmengda_wsw's math,so he give her a function f(x,k).
    f(x,k)=g8(x,k)
    gn(x,k)=gn1(g(x,k),k)
    where x[0,2301],k[0,2151].
    g(x,k)=(R(x)<<15)+(L(x)((R(x)k%(2151)))
    R(x)=x&(2151)
    L(x)=x>>15
    Here,  means xor, & means bitwise AND operation bit-by-bit.
    And f(x,k)[0,2301]

    The g(x,k) is defined as followed:

    R_clover gives Mengmengda_wsw x and f(x,k), and lets her calculate the value of k.
    However, it is so easy for Mengmengda_wsw. She enumerate all kinds of k,which adds up to 215=32768,and she can calculate it using computer。
    But R_clover won't let she solve the problem with computer, so he increases the difficluty.
    He provides x,f(f(x,k1),k2)     and Mengmengda_wsw has to calculate k1,k2.
    Now it is too hard for Mengmengda_wsw, can you help her?

输入格式

    The first line contains an integer T(1T40),which indicates the number of test cases.
    For the next T lines,each line contains two integers a,b where a,b[0,2301],   respectively indicating x and f(f(x,k1),k2)(k1,k2[0,2151]).

输出格式

    For each case, print two integers in a line, respectively indicating k1,k2. It is guaranteed that for each case there is only one solution.

输入样例

11063899164 441357888

输出样例

24533 30870
一道模拟+枚举题,首先我们可以看到f(x,k)里k的范围是[0,2^15-1],3W多一点,

其次,我们看到f(x)和g(x)的运算已经给出,我们可以分别写出逆函数_f(x)和_g(x)


题目给出,f(f(x,k1),k2)=y,那么我们已知用逆函数_f(x)枚举k2,逆求出所有可能的f(x,k1)的值,把k2和逆求出的f(x,k1)存在一个set里。

然后我们根据已知x的值,枚举k1,求出所有可能的f(x,k1),如果跟之前求出的set里的f(x,k1)的值匹配上了,那么就可以得到k1和k2了。

#include<cstdio>#include<cmath>#include<algorithm>#include<map>using namespace std;int M=(1<<15)-1;int gx(int x,int k){    int tmp=x&(M);    int tmp2=x>>15;    return (tmp<<15) + ( tmp2^((tmp*k)%M) );}int fx(int x,int k){    for(int i=0;i<8;i++){        x=gx(x,k);    }    return x;} int gx2(int x,int k){    int tmp=x&(M);    int tmp2=x>>15;    return tmp2 + ( (tmp^((tmp2*k)%M))<<15 );}int fx2(int x,int k){    for(int i=0;i<8;i++){        x=gx2(x,k);    }    return x;}map<int,int>rec;int main(){    int t;    int a,b,x,y;    for(scanf("%d",&t);t--;){        scanf("%d%d",&x,&y);        rec.clear();        for(int i=0;i<M;i++){            rec[fx(x,i)]=i;        }        for(int i=M;i>0;i--){            int t=fx2(y,i);            if(rec[t]){                printf("%d %d\n",rec[t],i);                break ;            }        }    }    return 0;}


0 0
原创粉丝点击