UVA10651
1 // 头一次写这种带位运算的题,不会啊 > < ,先开始根本没想到要位运算... 2 // 看了网上大神的做法,又问了学长才写完。 3 // 还是要好好看看位运算啊, 好勉强的才写出来 = = 4 #include<cstdio> 5 #include<cstring> 6 #include<algorithm> 7 #define MAX 4500 8 using namespace std; 9 int ans,vis[MAX]; 10 bool ck(int x,int pos) 11 { 12 if( (x&(1<<(pos-1))) && (x&(1<<pos)) && !(x&(1<<(pos+1))) ) return true; // 位与运算 检查该位 是否符合条件移除的条件 110 /011 13 if( !(x&(1<<(pos-1))) && (x&(1<<pos)) && (x&(1<<(pos+1))) ) return true; 14 return false ; 15 } 16 void dp(int x) 17 { 18 if(vis[x]) return ; // 如果此状态已访问就返回 19 for(int i=1;i<=10;i++) 20 { 21 if(ck(x,i)) // 符合条件就改变它的状态 22 { 23 int t=x; 24 t^=(1<<(i-1)); 25 t^=(1<<i); 26 t^=(1<<(i+1)); 27 dp(t); //继续搜索 28 } 29 } 30 int cnt=0; 31 for(int i=0;i<12;i++) // 找到此状态的最小值 32 if(x&(1<<i)) cnt++; 33 ans=(cnt<ans)?cnt:ans; // 与之前结果比较取最小 34 vis[x]=cnt; // 标记已访问 35 } 36 int main() 37 { 38 int n; 39 char str[15]; 40 scanf("%d",&n); 41 getchar(); 42 for(int i=0;i<n;i++) 43 { 44 gets(str); 45 memset(vis,0,sizeof(vis)); 46 int a=0; 47 for(int j=0;j<12;j++) // 位或运算 转成二进制数字 48 { 49 if(str[j]=='o') 50 a|=(1<<j); 51 } 52 ans=13; 53 dp(a); 54 printf("%d\n",ans); 55 } 56 return 0; 57 }