LGTB 玩扫雷
在一个n m 的棋盘上,有位置上有雷(用“*” 表示),其他位置是空地(用“.” 表示)。
LGTB 想在每个空地上写下它周围8 个方向相邻的格子中有几个雷。
请帮助他输出写了之后的棋盘
输入
第一行包含两个整数n, m 代表棋盘大小
接下来n 行,每行m 个字符,代表棋盘
1 n,m 1000
输出
输出包含n 行,每行m 个字符,代表LGTB 写了数字之后的棋盘
样例
样例输入
3 3
*.*
...
*.*
样例输出
*2*
242
*2*
解题报告:
拿到这道题,有两种解法,第一种是枚举每一个‘ . ’ ,搜它周围的‘ * ’的个数;第二种是枚举每一个‘ * ’,在它周围一圈不是‘ * ’的格子加上1,然后直接输出就可以了。先开始是想的第一种,又想了一下,这道题神奇地只有64M 的内存限制,好像雷更少一点,所以选择枚举雷。
但是又来了一个一直没怎么弄清楚地问题,读入char 和string 。先开始用的char 然后 scanf 结果只读了一行,gets()也读不全,就换成string cin>>s;一次性读一行来add 就好了。这里浪费了20多分钟吧。于是,这道水题我花了1个小时
结果又手抽地把判断边界 y<=m 打成了 y<=n (.....)就错了3组;
还学习到了一个读换行符的 getchar();
另外,还有从另一个可怜的同学那里吸取的教训 ios::sync_with_stdio(false); 加快cin速度的语句不能乱用。不与scanf混用。
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 using namespace std; 6 int n,m; 7 int mp[1005][1005]; 8 //char p[2]; 9 string s; 10 const int zl[2][8]={{-1,-1,-1,0,0,1,1,1},{-1,0,1,-1,1,-1,0,1}}; 11 void add(int a,int b) 12 { 13 mp[a][b]=-1; 14 for (int i=0;i<=7;i++) 15 { 16 int x=a+zl[0][i],y=b+zl[1][i]; 17 if (x>0&&x<=n&&y>0&&y<=m&&mp[x][y]>=0) 18 mp[x][y]++; 19 } 20 } 21 int main() 22 { 23 freopen("mine.in","r",stdin); 24 freopen("mine.out","w",stdout); 25 cin>>n>>m; 26 // p[0]='*'; 27 for (int i=1;i<=n;i++) 28 { 29 //memset(s,0,sizeof(s)); 30 cin>>s; 31 for (int j=0;j<=m-1;j++) 32 { 33 if (s[j]=='*') add(i,j+1); 34 } 35 36 } 37 for (int i=1;i<=n;i++) 38 { 39 for (int j=1;j<=m;j++) 40 { 41 if (mp[i][j]<0) 42 cout<<'*'; 43 else printf("%d",mp[i][j]); 44 } 45 printf(" "); 46 } 47 return 0; 48 }