题解 P1061 【Jam的计数法】
曦行夜落
2018-02-20 19:10:47
让我们以样例bdfij为例
bdfij,发现i和j已经无法进位(到底了),这时我们只能加f,变成g,同时将后面的字母变成g的连续后继(也就是h、i)
这时数字变为bdghi,然后我们发现i可以加,就加i
变成bdghj,这时j没得加了,只好加前面的h,变成i,i后面的字母变成连续后继,这时的数字是bdgij
这时我们发现,g是最右边的能增加的字母了,于是我们将g变成h,后面的字母变成连续后继(不变),这时变成bdhij
然后bdhij中后三个到达最大,于是我们加d,变成e,后面变成e的连续后继,也就是befgh,这时已经输出五个,直接结束
通过样例,我们可以整理一个简单的算法:
1.只要没有输出到五个并且不是最大的,继续循环
2.从后往前找出第一个可以加的字母
3.将其变成其后继
4.将它后面的全部字母变成它的连续后继
5.输出
6.跳回1重复执行
数据结构:lim数组存储最大值,a数组存储当前值
```cpp
#define maxn 50+5
#include<iostream>
#include<algorithm>
using namespace std;
char a[maxn],lim[maxn];
int main()
{
int s,t,w;
cin >> s >> t >> w;
for (int i=1;i<=w;++i)
cin >> a[i];
lim[w]=t+96;
for (int i=w-1;i>0;--i)
lim[i]=lim[i+1]-1;
// for (int i=1;i<=w;++i) cout << lim[i];
// cout << endl;
for (int i=1;i<6;++i)
{
int p=w;
while (a[p]==lim[p]) --p;
a[p]++;
for (int i=p+1;i<=w;++i) a[i]=a[i-1]+1;
int bo=1;
for (int i=1;i<=w;++i)
if (a[i]!=lim[i]) bo=0;
for (int i=1;i<=w;++i) cout << a[i];
cout << endl;
if (bo) break;
}
return 0;
}
```