【題目大意】
給定一個五子棋棋盤,判斷X棋一步之後能否勝利。
【解題思路】
沒什麼,自己寫模擬。遍歷每個可下的點判斷橫豎和斜方向上能否實現大於等於五子相連。
注意邊界問題,可以採用左右上下各拓展4行4列。
【解題代碼】
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define maxn 10010
using namespace std;
char map[20][20];
bool check(int a,int b)
{
map[a][b]=1;
// printf("begin check %d %d\n",a,b);
int conti,i,j;
for(conti=0,i=a-4;i<=a+4;i++) //橫向判斷
{
if(map[i][b]==1)
{
conti++;
if(conti>4) return true;
}
else
{
conti=0;
continue;
}
}
for(conti=0,j=b-4;j<=b+4;j++) //縱向判斷
{
if(map[a][j]==1)
{
conti++;
if(conti>4) return true;
}
else
{
conti=0;
continue;
}
}
for(conti=0,i=a-4,j=b-4;i<=a+4;i++,j++) //斜向判斷1
{
if(map[i][j]==1)
{
conti++;
if(conti>4) return true;
}
else
{
conti=0;
continue;
}
}
for(conti=0,i=a-4,j=b+4;i<=a+4;i++,j--) //斜向判斷1
{
if(map[i][j]==1)
{
conti++;
if(conti>4) return true;
}
else
{
conti=0;
continue;
}
}
map[a][b]=0;
return false;
}
int main()
{
// freopen("in.txt", "r", stdin);//其實in.txt是可以修改成其他名字的 比如“輸入.txt”,都是可以的,這裏只是爲了方便起見,下同;
for(int i=0+4;i<10+4;i++)
{
scanf("%s",map[i]+4);
}
for(int i=0+4;i<10+4;i++)
{
for(int j=0+4;j<10+4;j++)
{
switch(map[i][j])
{
case 'X': map[i][j]=1;break;
case 'O': map[i][j]=2;break;
case '.': map[i][j]=0;break;
}
// printf("%d ",map[i][j]);
}
// printf("\n");
}
int flag=0;
for(int i=0+4;i<10+4;i++)
{
for(int j=0+4;j<10+4;j++)
{
if(map[i][j]||!map[i-1][j]&&!map[i+1][j]&&!map[i][j-1]&&!map[i][j+1]&&!map[i-1][j-1]&&!map[i+1][j+1]&&!map[i-1][j+1]&&!map[i+1][j-1]) continue;
else flag=check(i,j);
if(flag)
{
// printf("%d %d \n",i-4,j-4);
break;
}
}
if(flag)
break;
}
if(flag)
printf("YES\n");
else printf("NO\n");
// fclose(stdin);
// fclose(stdout);
return 0;
}
【總結與反思】
模擬的時候要注意細節,儘量不要返工。
既然是遍歷,能簡化的簡化,比如判定周圍一圈沒有棋子可以直接continue跳過該循環。