【洛谷P1101】單詞方陣
阿新 • • 發佈:2018-12-27
題目大意:給一 \(n \times n\) 的字母方陣,內可能蘊含多個 \(“yizhong”\) 單詞。單詞在方陣中是沿著同一方向連續擺放的。擺放可沿著 8 個方向的任一方向,同一單詞擺放時不再改變方向,單詞與單詞之間可以交叉,因此有可能共用字母。輸出時,將不是單詞的字母用*代替,以突出顯示單詞。
題解:首先每個單詞擺放的方向要相同。因此,搜素對應的狀態應為當前位置的座標,需要比對的第幾個字母和麵朝哪個方向。搜尋時因為一個字母可能被多個字串公用,因此,不是很方便確定一個字母是否會不被列印,但是若經過這個字母可以組成單詞,則表明該字母一定在輸出時會被打印出來。所以,可以採用一個 vis[][] 陣列表示該字母是否需要被列印即可。
程式碼如下
#include <bits/stdc++.h> using namespace std; const int maxn=110; char mp[maxn][maxn],s[maxn]="yizhong"; int n;bool vis[maxn][maxn]; void read_and_parse(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%s",mp[i]+1); } const int dx[]={0,0,1,1,1,-1,-1,-1}; const int dy[]={1,-1,0,1,-1,0,1,-1}; bool dfs(int x,int y,int dir,int idx){ if(idx==6)return vis[x][y]=1; int xx=dx[dir]+x,yy=dy[dir]+y; if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&mp[xx][yy]==s[idx+1]&&dfs(xx,yy,dir,idx+1))return vis[xx][yy]=1; else return 0; } void solve(){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(mp[i][j]=='y'){ for(int k=0;k<8;k++) if(dfs(i,j,k,0))vis[i][j]=1; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++)printf("%c",vis[i][j]?mp[i][j]:'*'); puts(""); } } int main(){ read_and_parse(); solve(); return 0; }