Chips CodeForces

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;
}
原文地址:https://www.cnblogs.com/hehe54321/p/cf-333b.html