Codeforces Round #443(Div.2) C.Short Program(位运算+思维)

来源:互联网 发布:福建弘扬软件好不好 编辑:程序博客网 时间:2024/06/06 12:48

题目链接:Short Program
题意:给出一段程序,这段程序只有与、或、异或三种操作,程序有n(n<=5e5)行,每行一个操作符,一个操作数。程序输入一个数,输出一个数。题目要求你设计一个<=5行的程序,使得 输入0~1023每个数在源程序得到的结果和在你设计的程序得到的结果是一样的。
思路:由于我们不知道输入的数是多少,只知道这个数<=1023,转化为二进制也就是<=1111111111。设计的程序的输出和原来的程序的输出结果一样,如果能保证结果的每一个二进制位一样,那么结果也一样。所以应该通过结果倒过来设计程序。输入未知,结果自然未知,但是我们不要忽略了输入和结果的每个二进制位都只会在0-1变化,这是入手的关键点。
我们这样来操作,得到每一位如果是0,n次操作过后的0-1结果,同样得到每一位如果是1,n次操作过后的0-1结果。即让0走一遍n次操作,让1023走一遍n次操作,我们就知道每一位是0-1时n此操作过后应该变成什么。那么也就是4中搭配嘛,①0->0, 1->1 ②0->1, 1->1 ③0->0, 1->0 ④0->1, 1->0。第一种就是操作前后不变嘛,不操作。第二种就是对应位或1操作,其他位或0不改变。第三种就是对应位与0操作,其他位与1不改变。第四种就是对应位异或1操作,其他位异或0不改变。至此,设计程序即可,最多就3行,与、或、异或各一行。

这样做复杂度还很低,貌似就是输入的复杂度O(5e5)。原创代码,头铁,思考花了点时间。

#include <iostream>#include <cstdio>#include <fstream>#include <algorithm>#include <cmath>#include <deque>#include <vector>#include <queue>#include <string>#include <cstring>#include <map>#include <stack>#include <set>#define Max(a,b) a>b?a:b#define Min(a,b) a>b?b:a#define mem(a,b) memset(a,b,sizeof(a))using namespace std;typedef long long ll;int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};const double eps = 1e-6;const double Pi = acos(-1.0);const int INF=0x3f3f3f3f;const int maxn = 5e5+10;int zero[11], one[11];int yu[11],huo[11],yihuo[11];int main(){    int n,d;    char o;    scanf("%d",&n);    int a = 0, b = 1023;    for(int i = 0; i < n; i++){        getchar();        scanf("%c %d",&o,&d);        if(o == '|') a = a|d, b = b|d;        else if(o == '^') a = a^d, b = b^d;        else a = a&d, b = b&d;    }    int cnt = 1;    while(a != 0){        zero[cnt++] = a%2;        a = a/2;    }    cnt = 1;    while(b != 0){        one[cnt++] = b%2;        b = b/2;    }    for(int i = 1; i <= 10; i++) yu[i] = 1;    bool op1 = false, op2 = false, op3 = false;    for(int i = 1; i <= 10; i++){        if(zero[i] == 0 && one[i] == 0) yu[i] = 0, op1 = true;        else if(zero[i] == 1 && one[i] == 0) yihuo[i] = 1, op2 = true;        else if(zero[i] == 1 && one[i] == 1) huo[i] = 1, op3 = true;    }    int ans = 0;    int data[3];    if(op1){        ans++;        data[0] = 0;        for(int i = 1; i <= 10; i++){            data[0] += yu[i]*pow(2,i-1);        }    }    if(op2){        ans++;        data[1] = 0;        for(int i = 1; i <= 10; i++){            data[1] += yihuo[i] * pow(2,i-1);        }    }    if(op3){        ans++;        data[2] = 0;        for(int i = 1; i <= 10; i++){            data[2] += huo[i] * pow(2,i-1);        }    }    printf("%d\n",ans);    if(op1) printf("& %d\n",data[0]);    if(op2) printf("^ %d\n",data[1]);    if(op3) printf("| %d\n",data[2]);}
阅读全文
0 0
原创粉丝点击