HDU 4162 Shape Number(最小表示法)
2012-04-06 16:23
309 查看
题目: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)
大意:原串通过相邻的数字相减得到的差或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; }
相关文章推荐
- hdu 4162 Shape Number【循环字符串最小表示法】模板学习
- 【HDU 4162】Shape Number(一阶差分链码+最小表示法)
- 【最小表示法】HDU-4162-Shape Number
- HDU 4162 Shape Number 最小表示法
- hdu 4162 Shape Number(最小表示法)
- HDU 4162 Shape Number【字符串最小表示】
- HDU 4162 Shape Number(最小表示法)
- HDU 4162 Shape Number (最小表示法)
- HDU 4162 Shape Number 最小表示法
- hdu 4162 Shape Number 最小表示法
- HDOJ 4162 Shape Number(最小表示法 )
- Shape Number HDU - 4162(最小表示法)
- TOJ 3771 HDU 4162 Shape Number / 最小表示法
- 字符串_最小表示法求循环串的最小序列(HDU_4162)
- 【字符串最小表示】HDU 3374
- HDU - 2609 How many(最小表示法)
- HDU 3374 String Problem (KMP+最小最大表示)
- HDU 2609 How many(最小表示法)
- hdu 5442 Favorite Donut(最小表示法+kmp)
- HDU 2609 How Many [最小表示法] [字符串处理]