聲明
我的碼風可能有點和別人不太一樣(其實就是有點奇怪),大家重在意會即可。
原題傳送門
前言
作為一道被卡了1個小時才做出這道水題萌新,表示自己碼風有點菜,於是決定多做一點解釋,畢竟80行的代碼可能確實有點水QAQ。
60分騙分代碼詳解
首先,為了便於比對單詞,我建立了一個string類對象存儲題目要求的單詞(我表示並不清楚這個單詞是否有實際意義,如果有哪位大佬知道,歡迎在評論里告訴我)
string ans=" yizhong";
然后,n與m表示數組下標,用no表示該下標所應該對應的字母的編號,如:
int dfs(int n,int m,int no)
如果越界:
if(n<1||m<1||n>num||m>num)
return 0;
上深搜偽代碼:
1 int dfs(int n,int m,int no)
2 {
3 if(n<1||m<1||n>num||m>num)//如果越界則返回
4 return 0;
5 if(a[n][m]==ans[no])//如果是對應字母,則繼續深搜
6 {
7 if(no==7)//如果搜到最后一個,則返回1,表示深搜成功
8 {
9 book[n][m]=1;
10 return 1;
11 }
12 else
13 {
14 //搜索每一種可能
15 if(dfs(n+1,m,no+1)||dfs(n,m-1,no+1)||dfs(n,m+1,no+1)||dfs(n-1,m,no+1)||dfs(n+1,m-1,no+1)||dfs(n+1,m+1,no+1)||dfs(n-1,m-1,no+1)||dfs(n-1,m+1,no+1))
16 {
17 //若搜索成功,標記該字符是單詞的一部分
18 book[n][m]=1;
19 return 1;
20 }
21 else
22 return 0;
23 }
24 }
25 else//否則返回0
26 return 0;
27 }
大家仔細觀察便會發現該代碼的漏洞:他搜索所有的方向,因此如果有彎曲的字符連在一起與要求單詞相同,它便認為該字符是單詞的一部分,然而,題目要求必須是橫或豎或斜直着相連的字符串才參與比對,故若有該類型的數據,此代碼就會出錯(這便是他只能作為騙分代碼的原因)
最后,上你們最愛的完整代碼(第一個和第三個點會WA,原因上面已經解釋過,因此只能得60分)
1 #include<iostream>
2 #include <string>
3 using namespace std;
4
5 char a[102][102];
6 bool book[102][102]={0};//標記對應字符是否是要求單詞的一部分
7 int num;
8
9 int dfs(int n,int m,int no)
10 {
11 if(n<1||m<1||n>num||m>num)//如果越界則返回
12 return 0;
13 if(a[n][m]==ans[no])//如果是對應字母,則繼續深搜
14 {
15 if(no==7)//如果搜到最后一個,則返回1,表示深搜成功
16 {
17 book[n][m]=1;
18 return 1;
19 }
20 else
21 {
22 //搜索每一種可能
23 if(dfs(n+1,m,no+1)||dfs(n,m-1,no+1)||dfs(n,m+1,no+1)||dfs(n-1,m,no+1)||dfs(n+1,m-1,no+1)||dfs(n+1,m+1,no+1)||dfs(n-1,m-1,no+1)||dfs(n-1,m+1,no+1))
24 {
25 //若搜索成功,標記該字符是單詞的一部分
26 book[n][m]=1;
27 return 1;
28 }
29 else
30 return 0;
31 }
32 }
33 else//否則返回0
34 return 0;
35 }
36 int main()
37 {
38 //讀入
39 cin>>num;
40 for(int i=1;i<=num;i++)
41 for(int j=1;j<=num;j++)
42 {
43 cin>>a[i][j];
44 }
45 //深搜
46 for(int i=1;i<=num;i++)
47 for(int j=1;j<=num;j++)
48 dfs(i,j,1);
49 //輸出
50 for(int i=1;i<=num;i++)
51 {
52 for(int j=1;j<=num;j++)
53 {
54 if(book[i][j])
55 cout<<a[i][j];
56 else
57 cout<<"*";
58 }
59 cout<<endl;
60 }
61 return 0;
62 }
100分AC代碼詳解
我們說,上面的代碼只能得60分的原因在於他不判斷方向,而深搜所有的方向,因此會出錯,解決代碼也十分簡單:在dfs()函數中加一個表示方向的參數f即可:
1 int dfs(int n,int m,int no,int f)
2 {
3 if(n<1||m<1||n>num||m>num)//如果越界則返回
4 return 0;
5 if(a[n][m]==ans[no])//如果是對應字母,則繼續深搜
6 {
7 if(no==7)//如果搜到最后一個,則返回1,表示深搜成功
8 {
9 book[n][m]=1;
10 return 1;
11 }
12 else
13 {
14 //有選擇性的搜索
15 switch (f)
16 {
17 case 1: if(dfs(n-1,m-1,no+1,f)){book[n][m]=1;return 1;}else return 0;
18 case 2: if(dfs(n-1,m,no+1,f)){book[n][m]=1;return 1;}else return 0;
19 case 3: if(dfs(n-1,m+1,no+1,f)){book[n][m]=1;return 1;}else return 0;
20 case 4: if(dfs(n,m-1,no+1,f)){book[n][m]=1;return 1;}else return 0;
21 /*case 5表示no==1,
22 作為第一個字母,因此是個特例,要向所有方向搜索
23 其余情況都只向一個特定方向搜索*/
24 case 5:
25 if(dfs(n-1,m-1,no+1,1))
26 book[n][m]=1;
27 if(dfs(n-1,m,no+1,2))
28 book[n][m]=1;
29 if(dfs(n-1,m+1,no+1,3))
30 book[n][m]=1;
31 if(dfs(n,m-1,no+1,4))
32 book[n][m]=1;
33 if(dfs(n,m+1,no+1,6))
34 book[n][m]=1;
35 if(dfs(n+1,m-1,no+1,7))
36 book[n][m]=1;
37 if(dfs(n+1,m,no+1,8))
38 book[n][m]=1;
39 if(dfs(n+1,m+1,no+1,9))
40 book[n][m]=1;
41 break;
42 case 6: if(dfs(n,m+1,no+1,f)){book[n][m]=1;return 1;}else return 0;
43 case 7: if(dfs(n+1,m-1,no+1,f)){book[n][m]=1;return 1;}else return 0;
44 case 8: if(dfs(n+1,m,no+1,f)){book[n][m]=1;return 1;}else return 0;
45 case 9: if(dfs(n+1,m+1,no+1,f)){book[n][m]=1;return 1;}else return 0;
46 }
47
48 }
49 }
50 else//如果搜到最后一個,則返回1,表示深搜成功
51 return 0;
52 }
你們最愛的100分AC完整代碼:
1 #include<iostream>
2 #include <string>
3 using namespace std;
4
5 string ans=" yizhong";
6 char a[102][102];
7 bool book[102][102]={0};
8 int num;
9 int dfs(int n,int m,int no,int f);
10
11 int main()
12 {
13 freopen("cs.in","r",stdin);
14 cin>>num;
15 for(int i=1;i<=num;i++)
16 for(int j=1;j<=num;j++)
17 cin>>a[i][j];
18 for(int i=1;i<=num;i++)
19 for(int j=1;j<=num;j++)
20 dfs(i,j,1,5);
21 for(int i=1;i<=num;i++)
22 {
23 for(int j=1;j<=num;j++)
24 {
25 if(book[i][j])
26 cout<<a[i][j];
27 else
28 cout<<"*";
29 }
30 cout<<endl;
31 }
32 return 0;
33 }
34
35 int dfs(int n,int m,int no,int f)
36 {
37 if(n<1||m<1||n>num||m>num)//如果越界則返回
38 return 0;
39 if(a[n][m]==ans[no])//如果是對應字母,則繼續深搜
40 {
41 if(no==7)//如果搜到最后一個,則返回1,表示深搜成功
42 {
43 book[n][m]=1;
44 return 1;
45 }
46 else
47 {
48 //有選擇性的搜索
49 switch (f)
50 {
51 case 1: if(dfs(n-1,m-1,no+1,f)){book[n][m]=1;return 1;}else return 0;
52 case 2: if(dfs(n-1,m,no+1,f)){book[n][m]=1;return 1;}else return 0;
53 case 3: if(dfs(n-1,m+1,no+1,f)){book[n][m]=1;return 1;}else return 0;
54 case 4: if(dfs(n,m-1,no+1,f)){book[n][m]=1;return 1;}else return 0;
55 /*case 5表示no==1,
56 作為第一個字母,因此是個特例,要向所有方向搜索
57 其余情況都只向一個特定方向搜索*/
58 case 5:
59 if(dfs(n-1,m-1,no+1,1))
60 book[n][m]=1;
61 if(dfs(n-1,m,no+1,2))
62 book[n][m]=1;
63 if(dfs(n-1,m+1,no+1,3))
64 book[n][m]=1;
65 if(dfs(n,m-1,no+1,4))
66 book[n][m]=1;
67 if(dfs(n,m+1,no+1,6))
68 book[n][m]=1;
69 if(dfs(n+1,m-1,no+1,7))
70 book[n][m]=1;
71 if(dfs(n+1,m,no+1,8))
72 book[n][m]=1;
73 if(dfs(n+1,m+1,no+1,9))
74 book[n][m]=1;
75 break;
76 case 6: if(dfs(n,m+1,no+1,f)){book[n][m]=1;return 1;}else return 0;
77 case 7: if(dfs(n+1,m-1,no+1,f)){book[n][m]=1;return 1;}else return 0;
78 case 8: if(dfs(n+1,m,no+1,f)){book[n][m]=1;return 1;}else return 0;
79 case 9: if(dfs(n+1,m+1,no+1,f)){book[n][m]=1;return 1;}else return 0;
80 }
81
82 }
83 }
84 else//如果搜到最后一個,則返回1,表示深搜成功
85 return 0;
86 }
后記
相信大家看到這里,便會感到深搜原來就是這么簡單!記住:代碼長!=晦澀難懂!無需十分在意自己的碼風,能AC的代碼就是好代碼!最后,我辛苦敲了這么多,各位大佬能否給個贊呢?~~~