题解 P1061 【Jam的计数法】

曦行夜落

2018-02-20 19:10:47

Solution

让我们以样例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; } ```