HDU 4162 Shape Number(最小表示法)
題目:http://acm.hdu.edu.cn/showproblem.php?pid=4162
?
大意:原串通過相鄰的數字相減得到的差或8減該差得到一個新串,然后輸出新串(看成環)中字典序最小的
那個串。。。。
?
這里用到最小表示法:其維護i和j指針,分別指向(共有L(串長)個串)其中2個串(其實只有一個串,拆成2個串好理解點)的串頭(注意當比較這兩個串的大小的時候i和j都不動,任然指串頭,而這個串頭是指以該位置開始而得到的串的串頭),他是通過k(因為如果不引入k,而i和j是移動的,比較完成后i和j回不了串頭)來比較這兩個串,即i+k和j+k就是比較這兩個串時的指針。。。。。。。
?
然后,當不相等的時候,因為我們求的是最小的串,所以要移動大的指針,而小的指針不動,而這個小的指針很有可能就是我們所想要求的指針。。。。而移動的幅度是k+1使效率大大提高。。。。。因為如果移到[大指針后.....k]中的一個的話,
以這個位置為開頭的串也一定比小串大。。。。。注意一點,i或j指的位置都可能是想求的位置。。。。。。
總之,求最小表示,就小的不變,求最大表示就大不變。。。。。
還有一點,就是始終保持i<j,因為如果i == j的話事實上就在比較同一個串。。。。沒意義,而最后返回的就是i == j時
的指針,而這個指針極小可能是想要的結果。。。。。最后為什么返回小的那個呢?因為到達該位置就不在動了。。
而另外一個指針已經后移到出界了(即該指針 == l)
?
#include <iostream>#include <cstring>
using namespace std;
#define LL __int64
char c[333333], c1[333333];
//最小表示法
int Minp(char *c, int l)
{
int i = 0, j = 1, k = 0, t;
while (i < l && j < l && k < l)
{
t = c[(i+k)%l] - c[(j+k)%l];
if (t == 0)
{
k++;
}
else
{
if (t > 0)//以i開頭的串較大,所以i移動,j不變(因為求最小串的下標)
{
i += k + 1;
}
else//i處小
{
j += k + 1;
}
if (i == j)
{
j++;
}
k = 0;///
}
}
return i < j ? i : j;
}
int main()
{
int n;
int i, j;
int l, k;
while (~scanf("%s", c))
{
l = strlen(c);
for (i = 0; i < l; i++)
{
c1[i] = (c[(i+1)%l] >= c[i] ? c[(i+1)%l] - c[i] + '0' : 8 - (c[i] - c[(i+1)%l]) + '0');
}
//puts(c1);
k = Minp(c1, l);
//cout << k << endl;
for (i = 0, j = k; i < l; i++, j = (j+1)%l)
{
printf("%c", c1[j]);
}
puts("");
}
return 0;
}
轉載于:https://www.cnblogs.com/qiufeihai/archive/2012/04/06/2434869.html
總結
以上是生活随笔為你收集整理的HDU 4162 Shape Number(最小表示法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: core data firing fau
- 下一篇: [转]MSXML版本历史