1 条题解
-
0
自动搬运
来自洛谷,原作者为

AW_BCH
迷途.搬运于
2025-08-24 21:17:39,当前版本为作者最后更新于2025-03-01 23:25:55,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题解:B4183 [中山市赛 2024] 象战
题目分析
一道纯模拟,可以培养全面思考问题的能力,适合新手做。
观察 "象" 所在的位置,发现如果令 "象" 的坐标为 ,那么 、、、 都会是 "象" 可以攻击到的。
所以,如果 是
#,且 、、、 也都是#,那么这个点就是 "象" 所在的位置。代码实现
-
我们用
mp字符数组来表示这个棋盘。 -
我们用
pd函数来表示这个点是否符合成为 "象" 的标准。
代码:
//洛谷 B4183 [中山市赛 2024] 象战 #include<bits/stdc++.h> using namespace std; //#define int long long// #define endl '\n' #define emdl '\n' typedef long long ll; const int MAXN=8+5; int n=8; char mp[MAXN][MAXN]; bool pd(int x,int y){ if(mp[x][y]=='#'){ if(mp[x+1][y+1]=='#'){ if(mp[x+1][y-1]=='#'){ if(mp[x-1][y+1]=='#'){ if(mp[x-1][y-1]=='#'){ return 1; } else return 0; } else return 0; } else return 0; } else return 0; } else return 0; } signed main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>mp[i][j]; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(pd(i,j)){ cout<<i<<" "<<j<<endl; return 0; } } } return 0; }如果你是这么写的话,恭喜你,喜提 70 分。
为什么会这样呢?
仔细分析一下题意,我们会发现我们漏了一种情况没讨论。
什么情况呢?没错!是 "象" 所在的点在棋盘边缘的情况。
想到了情况,我们该怎么实现呢?
我想到了两种解决方案:
-
一种比较笨的方法。具体是枚举 "象" 在边缘的所有可能,并特殊处理。
-
比较聪明的办法。我们发现,无论 "象" 在边缘的哪里,实际上只用判断两种在棋盘内部的可能,另外两种可能会在棋盘外部,所以不妨初始化每个棋盘外部的点为
#,然后特判一下棋盘的四个顶点即可。
容易证明,上述方法都是对的。
真-代码实现
这里采用方案 2。
和上面代码不同的地方已近用注释展示了。
变量、数组、函数所表示的含义皆与上面的代码相同。
代码:
//洛谷 B4183 [中山市赛 2024] 象战 #include<bits/stdc++.h> using namespace std; //#define int long long// #define endl '\n' #define emdl '\n' typedef long long ll; const int MAXN=8+5; int n=8; char mp[MAXN][MAXN]; bool pd(int x,int y){ if(mp[x][y]=='#'){ if(mp[x+1][y+1]=='#'){ if(mp[x+1][y-1]=='#'){ if(mp[x-1][y+1]=='#'){ if(mp[x-1][y-1]=='#'){ return 1; } else return 0; } else return 0; } else return 0; } else return 0; } else return 0; } signed main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); //32 至 36 行有增改 for(int i=0;i<=n+1;i++){ for(int j=0;j<=n+1;j++){ mp[i][j]='#'; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>mp[i][j]; } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ //45 至 48 行有增改 if(i==1&&j==1) continue; if(i==1&&j==n) continue; if(i==n&&j==1) continue; if(i==n&&j==n) continue; //这里一定要 continue //题目保证了 "象" 不会在这里,无需担心正确性 if(pd(i,j)){ cout<<i<<" "<<j<<endl; return 0; } } } return 0; } -
- 1
信息
- ID
- 11588
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者