POJ 3316 Snakes on a Plane
题意:
给定一个有n*m的个网格的方块,蛇是由连续的网格组成的序列,并具有以下两个属性。
1,组成蛇身的网格的值为1;
2,蛇的每个格点附近(北/东/西/南)有且仅有有两个格点是1(蛇头蛇尾除外);
不能在蛇头和蛇尾增长的,能增长但会违反蛇的两个属性或碰到另一条蛇,称为最长蛇。求最长蛇的数量。
分析:
1,判断是否是蛇;
2,,判断在首尾两端增长时是否会合法(用扫雷游戏的手法来做,即求出每个格点的四 周的1的数量)
结:一直不能清晰的复述题意是迟迟做不出的这题的主要原因
View Code
#include<cstdio> #include<cstring> #include<cmath> #define MAXN 205 using namespace std; int c[MAXN][MAXN],step[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; char s[MAXN][MAXN]; bool isMax(int i,int j,int &k) { int t,ii,jj; s[i][j]='2'; if(c[i][j]<2) { for(t=0;t<4;t++) { ii=i+step[t][0]; jj=j+step[t][1]; if(s[ii][jj]=='0'&&c[ii][jj]==1) k++; } } for(t=0;t<4;t++) { ii=i+step[t][0]; jj=j+step[t][1]; if(s[ii][jj]=='1') { if(c[ii][jj]>2) return false; return isMax(ii,jj,k); } } return true; } int main() { int n,m,i,j,k,no; for(;scanf("%d%d",&n,&m),n+m;) { memset(c,0,sizeof(c)); for(i=0;i<=n+1;i++) s[i][0]='2',s[i][m+1]='\0'; for(j=0;j<=m+1;j++) s[0][j]=s[n+1][j]='2'; for(i=1;i<=n;i++) scanf("%s",s[i]+1); for(i=1;i<=n;i++) for(j=1;j<=m;j++) for(k=0;k<4;k++) if(s[i+step[k][0]][j+step[k][1]]=='1') c[i][j]++; for(i=1,no=0;i<=n;i++) for(j=1;j<=m;j++) if(s[i][j]=='1'&&c[i][j]<2) { k=0; if(isMax(i,j,k)&&!k) no++; } printf("%d\n",no); } return 0; }