模板题:POJ 1509 传送门
给你一个字符串,该字符串首尾相连,让你找到一个位置,使得该字符串从这个位置展开字符串字典序最小(大)。
例如一个字符串bacfea,该字符串从第六个位置展开,可以得到abacfe,字典序是最小的。
思路:首先设定x=k=0,y=1;x,y表示两个起点,k表示x和y开始连续的k个字符相同。这时候我们一直往后比较str[x+k]和str[y+k],有三种情况:
- str[x+k]==str[y+k] 则 k++。
- str[x+k]>str[y+k] 则 x+=k+1。
- str[x+k]<str[y+k] 则 y+=k+1。
第一种情况不解释了, 第二种情况为什么不是x++而是x+=k+1呢?因为我们上一步已经知道str[x]~ str[x+k-1]==str[y]~ str[y+k-1],但是现在有str[x+k]>str[y+k],所以我们在 str[x]~ str[x+k]中不可能找到比str[x+k+1]更好的起点。由于k+1
的不确定性,第二种和第三种情况最后都需要判断x是不是等于y,如果是的话必须要让其中一者++。另外,因为不符合条件的一者总是会更新到另一者后面,我们只需输出min(x,y)即可。
这些东西用文字解释起来总是很乱,看代码吧,模拟一下应该不难理解:
int MIN_MAX_PRESS(string temp)
{
temp = temp + temp;
int len = temp.size();
int x, y, k;
x = k = 0;
y = 1;
while (x + k < len && y + k < len)
{
if (temp[x + k] == temp[y + k])
k++;
else if (temp[x + k] > temp[y + k])
{
x += k + 1;
k = 0;
}
else
{
y += k + 1;
k = 0;
}
if (x == y)
x++;
}
return min(x + 1, y + 1);
}