Chips CodeForces - 333B
题意:有一个n*n的棋盘,其中有m个格子被禁止。在游戏开始前要将一些芯片(?)放到四条边上(但不能是角上)。游戏开始后,每次操作将每一个芯片移动到它四周四格中某一格,并且要用n-1次操作将所有的芯片移到与其初始位置相对的一条边上。在移动过程中,不能有任何芯片经过被禁止的格子,不能有任何多个芯片重叠,不能在一次操作中使两个芯片交换位置(在将两个芯片放在相对的两条边上相对的位置时,就会发生)。问如果要求完成游戏,最多可以在棋盘上放几个芯片。
方法:
事实上,当第i行不为中间行时,这一行是否有芯片、芯片在哪端与其他任何行/列的情况都无关。
但是当第i行是中间行时,如果第i行有芯片,第i列无法有芯片。
第一次程序(错)
1 #include<cstdio> 2 bool deny_row[1010],deny_column[1010]; 3 int ans,n,m; 4 int main() 5 { 6 int i,x,y; 7 scanf("%d%d",&n,&m); 8 for(i=1;i<=m;i++) 9 { 10 scanf("%d%d",&x,&y); 11 deny_row[x]=true; 12 deny_column[y]=true; 13 } 14 for(i=2;i<n;i++) 15 if(!deny_row[i]) 16 { 17 ans++; 18 deny_column[i]=true; 19 } 20 for(i=2;i<n;i++) 21 if(!deny_column[i]) 22 ans++; 23 printf("%d",ans); 24 return 0; 25 }
误以为第i行有芯片,第i列就一定不能有芯片。误以为一定要放在同一端。
第二次(正确)
#include<cstdio> bool deny_row[1010],deny_column[1010]; int ans,p,n,m; int main() { int i,x,y; scanf("%d%d",&n,&m); if(n%2==1) p=(n+1)/2;//记录中间行编号,如果其存在 for(i=1;i<=m;i++) { scanf("%d%d",&x,&y); deny_row[x]=true; deny_column[y]=true; } for(i=2;i<n;i++) if(!deny_row[i]) ans++; for(i=2;i<n;i++) if(!deny_column[i]&&(deny_row[i]==true||i!=p)) ans++; printf("%d",ans); return 0; }