【搜索】單詞方陣


聲明


我的碼風可能有點和別人不太一樣(其實就是有點奇怪),大家重在意會即可
原題傳送門

前言


作為一道被卡了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的代碼就是好代碼!最后,我辛苦敲了這么多,各位大佬能否給個贊呢?~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM