洛谷-DFS-1101-单词方阵-个人AC题解及公共题解的笔记
先上自己AC代碼(博主這個(gè)代碼修改過多次,只因代碼長度過長)
#include<bits/stdc++.h> using namespace std; #define MAXN 102 int flag; int n; int next1[8][2]={{1,0},{0,1},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}}; char map1[MAXN][MAXN],map2[MAXN][MAXN]; const char word[7]={'y','i','z','h','o','n','g'}; int dfs(int x,int y,int now,int next_direction) {if(map1[x][y]=='g'){flag=1;map2[x][y]=map1[x][y];return 1;}int tx,ty;tx=x+next1[next_direction][0];ty=y+next1[next_direction][1];if(map1[tx][ty]==word[now+1] && tx>=0 && tx<n && ty>=0 && ty<n){if(dfs(tx,ty,now+1,next_direction)){map2[tx][ty]=map1[tx][ty];return 1;}}return 0; } int main() {cin>>n;memset(map2,'*',sizeof(map2));for(int i=0;i<n;i++){cin>>map1[i];}for(int i=0;i<n;i++){for(int j=0;j<n;j++){flag=0;if(map1[i][j]!='y'){continue;}if(map1[i][j]=='y' && map2[i][j]=='*'){for(int k=0;k<8;k++){map2[i][j]=map1[i][j];if(!dfs(i,j,0,k) && flag==0){map2[i][j]='*';}}} }}for(int i=0;i<n;i++){for(int j=0;j<n;j++){printf("%c",map2[i][j]);}cout<<endl;}return 0; }說說思路:在本題中,由于題目說了單詞方向是一致,不會(huì)中途改方向,所以我們只需要找到一個(gè)頭,然后在其八周進(jìn)行八序遍歷,如果滿足單詞下一個(gè)字母,則滿足條件,同時(shí)保留該方向,做為DFS的方向.同時(shí),博主在這里的思路是創(chuàng)建兩個(gè)單詞方陣,一個(gè)用來判斷,一個(gè)用來進(jìn)行DFS的搜索和改變*的值使其成為顯眼的單詞,所以有map1和map2
在這里講一下博主做題中的失誤,一開始博主認(rèn)為"yizhong"這個(gè)單詞,應(yīng)該既可以從’y’作為頭,也可以從’g’作為頭,只需要在常字符數(shù)組中,進(jìn)行序號(hào)的增減即可,所以如果我們是以’y’開頭,則對(duì)于word數(shù)組,每次將下標(biāo)加一則指向下一個(gè)字母,同理,如果我們是以’g’開頭,則每次將下標(biāo)減一則指向下一個(gè)字母,不過后來發(fā)現(xiàn),既然博主采取了枚舉所有的字母的方式,那么對(duì)于分’y’和’g’來說其實(shí)是沒有意義的,不如將其刪減為只有’y’或者’g’,不過這也是一個(gè)可以保留的思想.
此外
博主在這里采取的是判斷的同時(shí)進(jìn)行dfs,即如果下一個(gè)字母配對(duì)成功,則繼續(xù)進(jìn)行dfs,直到拼湊成一個(gè)完整的單詞為止,此時(shí)則返回True,一步步返回.
(文末附上博主一開始AC代碼)
? ?說說洛谷題解
題解一
#include <bits/stdc++.h> using namespace std;const int maxn=100+10; struct node {int x,y; }c[maxn];//記錄路徑 char fz[maxn][maxn],stand[]="yizhong";//fz保存單詞矩陣,stand保存保準(zhǔn)的“yizhong”便于匹配 int vis[maxn][maxn];//保存路徑,是否該點(diǎn)為答案 int dir[][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};//八向的常量數(shù)組 void dfs(int x,int y,node c[],int k,int cur) {if(cur==7){for(int i=0;i<7;i++)vis[c[i].x][c[i].y]=1;}else{int dx=x+dir[k][0];//沿著正確的k方向搜索int dy=y+dir[k][1];if(cur==6||fz[dx][dy]==stand[cur+1]){c[cur].x=x;c[cur].y=y;dfs(dx,dy,c,k,cur+1);}} } int main() {freopen("input.txt","r",stdin);int n;scanf("%d",&n);for(int i=0;i<n;i++)scanf("%s",fz[i]);memset(vis,0,sizeof(vis));for(int i=0;i<n;i++)//搜索y,i相連的可能的方向k,以k為方向進(jìn)行DFSfor(int j=0;j<n;j++)if(fz[i][j]=='y') for(int k=0;k<8;k++){int x=i+dir[k][0];int y=j+dir[k][1];if(fz[x][y]=='i')dfs(i,j,c,k,0);}for(int i=0;i<n;i++){//輸出結(jié)果for(int j=0;j<n;j++)if(vis[i][j]) printf("%c",fz[i][j]);else printf("*");printf("\n");}return 0; }此篇洛谷題解大致思路和博主差不多,都是先從’y’開始,再找到’i’,如果滿足,就保留’y’到’i’的方向,然后繼續(xù)進(jìn)行搜尋.
題解二
博主提出這個(gè)題解也是為題目提供第二種思路,把DFS打成大模擬,下面上代碼
#include<bits/stdc++.h> using namespace std; char a[10001][10001],b[10001][10001]; int main(){int n;cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>a[i][j];b[i][j]='*';}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(a[i][j]=='y'){//從左往右 if(a[i][j+1]=='i'){if(a[i][j+2]=='z'){if(a[i][j+3]=='h'){if(a[i][j+4]=='o'){if(a[i][j+5]=='n'){if(a[i][j+6]=='g'){b[i][j]=a[i][j];b[i][j+1]=a[i][j+1];b[i][j+2]=a[i][j+2];b[i][j+3]=a[i][j+3];b[i][j+4]=a[i][j+4];b[i][j+5]=a[i][j+5];b[i][j+6]=a[i][j+6];} } } } } } }if(a[i][j]=='y'){//從上往下 if(a[i+1][j]=='i'){if(a[i+2][j]=='z'){if(a[i+3][j]=='h'){if(a[i+4][j]=='o'){if(a[i+5][j]=='n'){if(a[i+6][j]=='g'){b[i][j]=a[i][j];b[i+1][j]=a[i+1][j];b[i+2][j]=a[i+2][j];b[i+3][j]=a[i+3][j];b[i+4][j]=a[i+4][j];b[i+5][j]=a[i+5][j];b[i+6][j]=a[i+6][j];} } } } } } }if(a[i][j]=='y'){//從左上往左下 if(a[i+1][j+1]=='i'){if(a[i+2][j+2]=='z'){if(a[i+3][j+3]=='h'){if(a[i+4][j+4]=='o'){if(a[i+5][j+5]=='n'){if(a[i+6][j+6]=='g'){b[i][j]=a[i][j];b[i+1][j+1]=a[i+1][j+1];b[i+2][j+2]=a[i+2][j+2];b[i+3][j+3]=a[i+3][j+3];b[i+4][j+4]=a[i+4][j+4];b[i+5][j+5]=a[i+5][j+5];b[i+6][j+6]=a[i+6][j+6];} } } } } } }if(a[i][j]=='y'){//從上右下往左上 if(a[i-1][j-1]=='i'){if(a[i-2][j-2]=='z'){if(a[i-3][j-3]=='h'){if(a[i-4][j-4]=='o'){if(a[i-5][j-5]=='n'){if(a[i-6][j-6]=='g'){b[i][j]=a[i][j];b[i-1][j-1]=a[i-1][j-1];b[i-2][j-2]=a[i-2][j-2];b[i-3][j-3]=a[i-3][j-3];b[i-4][j-4]=a[i-4][j-4];b[i-5][j-5]=a[i-5][j-5];b[i-6][j-6]=a[i-6][j-6];} } } } } } }if(a[i][j]=='y'){//從右往左 if(a[i][j+1]=='i'){if(a[i][j-2]=='z'){if(a[i][j-3]=='h'){if(a[i][j-4]=='o'){if(a[i][j-5]=='n'){if(a[i][j-6]=='g'){b[i][j]=a[i][j];b[i][j-1]=a[i][j-1];b[i][j-2]=a[i][j-2];b[i][j-3]=a[i][j-3];b[i][j-4]=a[i][j-4];b[i][j-5]=a[i][j-5];b[i][j-6]=a[i][j-6];} } } } } } }if(a[i][j]=='y'){//從下往上 if(a[i-1][j]=='i'){if(a[i-2][j]=='z'){if(a[i-3][j]=='h'){if(a[i-4][j]=='o'){if(a[i-5][j]=='n'){if(a[i-6][j]=='g'){b[i][j]=a[i][j];b[i-1][j]=a[i-1][j];b[i-2][j]=a[i-2][j];b[i-3][j]=a[i-3][j];b[i-4][j]=a[i-4][j];b[i-5][j]=a[i-5][j];b[i-6][j]=a[i-6][j];} } } } } } }if(a[i][j]=='y'){//從左往右 if(a[i-1][j+1]=='i'){if(a[i-2][j+2]=='z'){if(a[i-3][j+3]=='h'){if(a[i-4][j+4]=='o'){if(a[i-5][j+5]=='n'){if(a[i-6][j+6]=='g'){b[i][j]=a[i][j];b[i-1][j+1]=a[i-1][j+1];b[i-2][j+2]=a[i-2][j+2];b[i-3][j+3]=a[i-3][j+3];b[i-4][j+4]=a[i-4][j+4];b[i-5][j+5]=a[i-5][j+5];b[i-6][j+6]=a[i-6][j+6];} } } } } } }if(a[i][j]=='y'){//從左往右 if(a[i+1][j-1]=='i'){if(a[i+2][j-2]=='z'){if(a[i+3][j-3]=='h'){if(a[i+4][j-4]=='o'){if(a[i+5][j-5]=='n'){if(a[i+6][j-6]=='g'){b[i][j]=a[i][j];b[i+1][j-1]=a[i+1][j-1];b[i+2][j-2]=a[i+2][j-2];b[i+3][j-3]=a[i+3][j-3];b[i+4][j-4]=a[i+4][j-4];b[i+5][j-5]=a[i+5][j-5];b[i+6][j-6]=a[i+6][j-6];} } } } } } } } } for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cout<<b[i][j];}cout<<endl; } }這題的最長代碼
?
雖然這個(gè)辦法是很傻,但是不失為一種思路,當(dāng)做不出來的時(shí)候,當(dāng)大模擬來打(混分),當(dāng)然前提是可以當(dāng)作大模擬打嗷
?
?
?
然后補(bǔ)一個(gè)代碼簡化:即將方向代碼next[8][2]改成如下代碼:
END
差點(diǎn)忘了博主一開始的冗余代碼
/*關(guān)于此題思路,dfs從'y'或者'g'開始,并給予1,-1作為方向的標(biāo)識(shí)*/ /*一個(gè)單詞的方向不變,所以dfs 只用找一個(gè)方向,保留next[i][2]的i */ /*用一個(gè)常字符數(shù)組來保留目標(biāo)單詞 */ /*遇到非y,g的 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXN 102 int flag; int n; int sum; int next1[8][2]={{1,0},{0,1},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}}; char map1[MAXN][MAXN],map2[MAXN][MAXN]; const char word[7]={'y','i','z','h','o','n','g'}; int dfs(int x,int y,int direction,int now,int next_direction) {/*if(direction==1 && map1[x][y]=='g'){map2[x][y]=map1[x][y];return 1;}else if(direction==-1 && map1[x][y]=='y'){map2[x][y]=map1[x][y];return 1;}*/int tx,ty;tx=x+next1[next_direction][0];ty=y+next1[next_direction][1];if(tx<0 || tx>=n || ty<0 || ty>=n){return 0;}if(map1[tx][ty]==word[now+direction]){sum++;if(sum==7){flag=1;map2[tx][ty]=map1[tx][ty];return 1;}if(dfs(tx,ty,direction,now+direction,next_direction)){map2[tx][ty]=map1[tx][ty];return 1;}}return 0; } int main() {int start;int direction;cin>>n;memset(map2,'*',sizeof(map2));for(int i=0;i<n;i++){cin>>map1[i];}for(int i=0;i<n;i++){for(int j=0;j<n;j++){flag=0;if(!(map1[i][j]=='y' || map1[i][j]=='g')){continue;}if(map1[i][j]=='y' && map2[i][j]=='*'){direction=1;start=0;for(int k=0;k<8;k++){sum=1;map2[i][j]=map1[i][j];if(!dfs(i,j,direction,start,k) && flag==0){map2[i][j]='*';}}}else if(map1[i][j]=='g' && map2[i][j]=='*'){direction=-1;start=6;for(int k=0;k<8;k++){sum=1;map2[i][j]=map1[i][j];if(!dfs(i,j,direction,start,k) && flag==0){map2[i][j]='*';}}}}}for(int i=0;i<n;i++){for(int j=0;j<n;j++){printf("%c",map2[i][j]);}cout<<endl;}//getchar();//getchar();return 0; }?
END
總結(jié)
以上是生活随笔為你收集整理的洛谷-DFS-1101-单词方阵-个人AC题解及公共题解的笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自己搭建的CISCO实验环境
- 下一篇: 数据中心机房建设方案