1 条题解

  • 0
    @ 2025-8-24 21:17:40

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar AW_BCH
    迷途.

    搬运于2025-08-24 21:17:39,当前版本为作者最后更新于2025-03-01 23:25:55,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题解:B4183 [中山市赛 2024] 象战

    题目传送门

    更好的阅读体验

    题目分析

    一道纯模拟,可以培养全面思考问题的能力,适合新手做。

    观察 "象" 所在的位置,发现如果令 "象" 的坐标为 (x,y)(x,y),那么 (x+1,y+1)(x+1,y+1)(x+1,y1)(x+1,y-1)(x1,y+1)(x-1,y+1)(x1,y1)(x-1,y-1) 都会是 "象" 可以攻击到的。

    所以,如果 (x,y)(x,y)#,且 (x+1,y+1)(x+1,y+1)(x+1,y1)(x+1,y-1)(x1,y+1)(x-1,y+1)(x1,y1)(x-1,y-1) 也都是 #,那么这个点就是 "象" 所在的位置。

    代码实现

    • 我们用 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 分

    为什么会这样呢?

    仔细分析一下题意,我们会发现我们漏了一种情况没讨论。

    什么情况呢?没错!是 "象" 所在的点在棋盘边缘的情况。

    想到了情况,我们该怎么实现呢?

    我想到了两种解决方案:

    1. 一种比较笨的方法。具体是枚举 "象" 在边缘的所有可能,并特殊处理。

    2. 比较聪明的办法。我们发现,无论 "象" 在边缘的哪里,实际上只用判断两种在棋盘内部的可能,另外两种可能会在棋盘外部,所以不妨初始化每个棋盘外部的点为 #,然后特判一下棋盘的四个顶点即可。

    容易证明,上述方法都是对的。

    真-代码实现

    这里采用方案 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
    上传者