洛谷 P1061 Jam的计数法

传送门

 

题解:

  相关变量解释:

1 int s,t,w;
2 int tot=0;//最多输出五组
3 int maxNum[maxn];//maxNum[i] : i 位置可以达到的最大值
4 char letter[maxn];

  深搜步骤:

  (1):预处理出num[ ],maxNum[ ]

1 for(int i=1;i <= w;++i)
2     num[i]=letter[i-1]-'a'+1;//将单词转换成数字
3 for(int i=w;i >= 1;--i)
4     maxNum[i]=t--;//求出i位置可达到的最大值

  (2):从w开始往前遍历,找到数值可以变大的位置,在通过Dfs( )求出由于当前位置影响而满足条件的Jam数

 1 int index=w;
 2 while(index >= 1)//从后往前遍历
 3 {
 4     while(num[index] < maxNum[index])//判断当前位置是否可以变得更大
 5     {
 6         num[index]++;
 7         Dfs(index,index+1,num);//求出受当前位置变大的影响的Jam数
 8     }
 9     index--;
10 }

  (3):Dfs( )

 1 void Dfs(int start,int curPos,int num[])
 2 {
 3     if(tot == 5)
 4         return ;
 5     //curPos == w+1 作用 : 特判index == 1的情况
 6     if(curPos == w || curPos == w+1)
 7     {
 8         if(curPos == w)//特判
 9             num[w]=num[w-1]+1;
10         while(num[w] <= maxNum[w])//判断w位置的数是否可以变大
11         {
12             Print(num);//打印答案
13             tot++;
14             if(tot == 5)
15                 return ;
16             num[w]++;
17         }
18         int prePos=w-1;//回溯,查找w位置之前,start位置之后第一个变大的位置
19         while(prePos > start && num[prePos] == maxNum[prePos])
20             prePos--;
21         if(prePos > start)//找到
22         {
23             num[prePos]++;
24             Dfs(start,prePos+1,num);
25         }
26         return ;
27     }
28     num[curPos]=num[curPos-1]+1;
29     Dfs(start,curPos+1,num);
30 }

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=30;
 5 
 6 int s,t,w;
 7 int tot=0;//最多输出五组
 8 int maxNum[maxn];//maxNum[i] : i 位置可以达到的最大值
 9 char letter[maxn];
10 
11 void Print(int num[])
12 {
13     for(int i=1;i <= w;++i)
14         printf("%c",num[i]-1+'a');
15     printf("\n");
16 }
17 void Dfs(int start,int curPos,int num[])
18 {
19     if(tot == 5)
20         return ;
21     if(curPos == w || curPos == w+1)
22     {
23         if(curPos == w)
24             num[w]=num[w-1]+1;
25         while(num[w] <= maxNum[w])
26         {
27             Print(num);
28             tot++;
29             if(tot == 5)
30                 return ;
31             num[w]++;
32         }
33         int prePos=w-1;
34         while(prePos > start && num[prePos] == maxNum[prePos])
35             prePos--;
36         if(prePos > start)
37         {
38             num[prePos]++;
39             Dfs(start,prePos+1,num);
40         }
41         return ;
42     }
43     num[curPos]=num[curPos-1]+1;
44     Dfs(start,curPos+1,num);
45 }
46 void Solve()
47 {
48     int num[maxn];
49     for(int i=1;i <= w;++i)
50         num[i]=letter[i-1]-'a'+1;//将单词转换成数组
51     for(int i=w;i >= 1;--i)
52         maxNum[i]=t--;//求出i位置可达到的最大值
53     int index=w;
54     while(index >= 1)
55     {
56         while(num[index] < maxNum[index])
57         {
58             num[index]++;
59             Dfs(index,index+1,num);
60         }
61         index--;
62     }
63 }
64 int main()
65 {
66     scanf("%d%d%d",&s,&t,&w);
67     scanf("%s",letter);
68     Solve();
69 }
Dfs

大神Dfs()精简代码:

https://rainman.blog.luogu.org/solution-p1061

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int s,t,w,c;
 5 int a[30],cnt;
 6 
 7 inline void output()
 8 {
 9     for(int i=1;i<=w;i++)
10     cout<<(char)('a'+a[i]-1);
11     cout<<endl;
12 }
13 
14 void dfs(int pos,int step)
15 {
16     if(pos==0)
17         return;
18     if(step == 6)
19         return;
20     if(a[pos] < t && a[pos] < a[pos+1]-1)
21     {
22         a[pos]++;
23         for(int i=pos+1;i<=w;i++)
24             a[i]=a[i-1]+1;
25         output();
26         dfs(w,step+1);
27     }
28     else 
29         dfs(pos-1,step);
30 }
31 
32 int main()
33 {
34     cin>>s>>t>>w;
35     fflush(stdin);
36     while((c=getchar())!=EOF)
37     {
38         int temp=c-'a'+1;
39         if(temp>=1&&temp<=26)
40             a[++cnt]=temp;
41     }
42     a[w+1]=0x7f;
43     dfs(w,1);
44     return 0;
45 }
Dfs

 

posted @ 2018-11-29 11:19  HHHyacinth  阅读(226)  评论(0编辑  收藏  举报