原题链接:http://codeforces.com/problemset/problem/878/A
题意:给出n个位运算操作, 化简这些操作, 使化简后的操作次数不多于5步。
思路:我们可以对二进制每一位上的1, 0, 进行讨论,
如果n次操作后1 -->1, 0 --> 1, 说明这一位要用或操作(or 1)
类似的,1 -->0, 0 -->1, 说明这一位要用异或操作(xor 1)
1 -->0, 0 -->0, 说明这一位要用与操作(and 0)
1 -->1, 0 -->0,前后不变,可以不用进行操作。
其中,and 0 操作可以用 or 1 xor 1代替, 那么最后化简后的操作次数不会超过 2 次。
AC代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<iomanip> 5 #include<algorithm> 6 #include<string> 7 using namespace std; 8 typedef long long LL; 9 int XOR, OR; 10 int p[11]; 11 int b1,b2; 12 char ch[500005]; 13 int num[500005][11]; 14 int cal(int b, int j, int i){ 15 if(ch[j]=='|') return b|num[j][i]; 16 if(ch[j]=='&') return b&num[j][i]; 17 else return b^num[j][i]; 18 } 19 int main() 20 { 21 int n,m; 22 p[0]=1; 23 for(int i=1;i<11;i++) p[i]=p[i-1]*2; 24 while(cin>>n) 25 { 26 XOR=OR=0; 27 memset(num, 0, sizeof(num)); 28 for(int i=0;i<n;i++){ 29 scanf(" %c %d", &ch[i], &m); 30 int t=0; 31 while(m){ 32 if(m&1) num[i][t]=1; 33 t++; 34 m>>=1; 35 } 36 } 37 for(int i=0;i<10;i++){ 38 b1=1,b2=0; 39 for(int j=0;j<n;j++){ 40 b1=cal(b1, j, i); 41 b2=cal(b2, j, i); 42 } 43 if(b1==0&&b2==0){//n and 1 相当于 n or 1 xor 1 44 OR^=p[i]; 45 XOR^=p[i]; 46 } 47 if(b1==1&&b2==1) OR^=p[i]; 48 if(b1==0&&b2==1) XOR^=p[i]; 49 } 50 int sum=0; 51 if(OR) sum++; 52 if(XOR) sum++; 53 cout<<sum<<endl; 54 55 if(OR) cout<<'|'<<' '<<OR<<endl; 56 if(XOR) cout<<'^'<<' '<<XOR<<endl; 57 } 58 }