洛谷題解 P1331 海戰
阿新 • • 發佈:2020-09-10
原題傳送門
0.前言 依舊是一個簡單的搜尋訓練呢...
1.演算法 DFS或BFS均可(此處使用DFS)
2.思路
看見樣例,依然還是一道簡單的搜尋題。
這道題在原先是 普及/提高- 的題,後來是不是因為太簡單被調了
可以把這道題主要要完成的操作:
- 搜尋+統計船的個數
- 判斷是否有船相鄰
其中第一個操作非常好完成。就是就是一個簡單的搜尋遍歷。
但是第二個操作就有些難度。
這裡需要運用到一些技巧(找規律)
通過找規律我們可以發現,當在相鄰的4個方格中,有三個是“*”時,則船會相鄰
因為只能出現一下這四種不合法的情況:
* * * * * . . * * . . * * * * *
3.程式碼
#include<iostream> #include<cstdio> using namespace std; inline void read(int &x){ //快讀 int f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } x*=f; } int x,y; char map[1001][1001]; //存圖 int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1}; //上下左右遍歷的輔助陣列 inline bool judge(int m,int n){ //判斷是否有船相鄰的情況 int cnt=0; if(map[m][n]=='#') cnt++; if(map[m+1][n]=='#') cnt++; if(map[m][n+1]=='#') cnt++; if(map[m+1][n+1]=='#') cnt++; if(cnt==3) return false; else return true; } inline void DFS(int p,int q){ map[p][q]='^'; //把與當前(即"#")節點標成一個統一的符號 //為了和原"#"區分(因為是同一艘船) for(int i=1;i<=4;i++){ if(p+dx[i]<0||p+dx[i]>x+1||q+dy[i]<0||q+dy[i]>y+1) continue; //邊界條件不要忘 if(map[p+dx[i]][q+dy[i]]=='#'){ //當前節點也是船的時候才能繼續遍歷 DFS(p+dx[i],q+dy[i]); } } } int ans; int main(){ read(x);read(y); for(int i=1;i<=x;i++){ for(int j=1;j<=y;j++){ cin>>map[i][j]; } } for(int i=1;i<=x;i++){ for(int j=1;j<=y;j++){ if(judge(i,j)==false){ printf("Bad placement."); //注意句號qwq return 0; } } } for(int i=1;i<=x;i++){ for(int j=1;j<=y;j++){ if(map[i][j]=='#'){ //只要有"#",就有一艘船 ans++; DFS(i,j); //把整艘船全部搜出來 } } } printf("There are %d ships.",ans); //注意句號qwq return 0; }