TYVJ1266 费解的开关
恩,这题......
看看题面想到了啥?炮兵阵地!
再仔细一思考:炮兵阵地是求放置最多,而这个显然可以递推得出。
由于每个格子至多点一次,那么我们发现:
在第一行点击状态确定的情况下,后面每个格子的点击与否都是确定的。那么我们点完之后判断一下最后一行合不合法即可。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #define say printf("*") 5 using namespace std; 6 const int N = 6,INF = 0x3f3f3f3f; 7 int a[N][N],f[N][N]; 8 void out() 9 { 10 printf("\n"); 11 for(int i=1; i<=5; i++) 12 { 13 for(int j=1; j<=5; j++) printf("%d ",a[i][j]); 14 printf("\n"); 15 } 16 return; 17 } 18 bool check(int x,int y) 19 { 20 return x<=5&&x>=1&&y<=5&&y>=1; 21 } 22 void click(int x,int y) 23 { 24 //printf("click:%d %d\n",x,y); 25 a[x][y]^=1; 26 if(check(x,y+1)) a[x][y+1]^=1; 27 if(check(x,y-1)) a[x][y-1]^=1; 28 if(check(x+1,y)) a[x+1][y]^=1; 29 if(check(x-1,y)) a[x-1][y]^=1; 30 //out(); 31 return; 32 } 33 int cal(int x) 34 { 35 int a[14],ans=0; 36 for(int i=0;i<14;i++) a[i]=bool(x&(1<<i)); 37 for(int i=13;i>=0;i--) ans=ans*10+a[i]; 38 return ans; 39 } 40 int main() 41 { 42 int T,s,ans;char ch; 43 scanf("%d",&T); 44 while(T--) 45 { 46 ans=INF; 47 for(int i=1; i<=5; i++) ///读入 48 { 49 for(int j=1;j<=5;j++) 50 { 51 ch=getchar(); 52 while(ch!='0'&&ch!='1') ch=getchar(); 53 f[i][j]=ch-'0'; 54 } 55 } 56 for(int i=0; i<(1<<5); i++) ///第一行 57 { 58 s=0; 59 for(int j=1; j<=5; j++)///复制 60 { 61 for(int k=1; k<=5; k++) a[j][k]=f[j][k]; 62 } 63 for(int j=4; j>=0; j--)///处理第一行 64 if((1<<j)&i) {click(1,5-j);s++;} 65 for(int j=1;j<=4;j++) ///处理后四行 66 { 67 for(int k=1;k<=5;k++) 68 if(!a[j][k]) {click(j+1,k);s++;} 69 } 70 bool bo=0; 71 for(int j=1;j<=5;j++) 72 if(!a[5][j]) bo=1; 73 if(bo) continue; 74 //printf("%d %d %d\n",cal(i),ans,s); 75 ans=min(ans,s); 76 } 77 printf("%d\n",(ans<=6?ans:-1)); 78 } 79 80 81 return 0; 82 }