题目链接:hdu4162
题目大意:总之就是在介绍计算机视觉中链码的东西。给一个数字串,先如果相邻差值为负数的话要将结果+8否则记录结果。最后将这个串看成一个循环串,打印字典序最小的串表示(求同构串)。
解题思路:先预处理一下,注意边界相减是原串而不是更新完的结果!然后利用最小表示法求同构串。预处理:ans[i] = ((str[(i+1)len]-str[i])+8)%8。
AC代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <utility>
using namespace std;
inline int Min (int a, int b) {
return a>b?b:a;
}
string min_Show (string& str) {
int i = 0,j = 1,k = 0,len = str.size();
while (i < len && j < len && k < len) {
int cmp = str.at((i + k) % len) - str.at((j + k) % len);
if(cmp == 0) {
k++;
}else {
if(cmp > 0) {
i = i + k + 1;
}else {
j = j + k + 1;
}
if(i == j) {
j++;
}
k = 0;
}
}
i = Min(i, j);
return str.substr(i) + str.substr(0, i); //长度为i不是i+1因为i为起点0~i-1
}
int main() {
ios::sync_with_stdio(false);
string str;
char ch;
while (cin >> str) {
ch = *str.begin();
for (string::iterator it = str.begin() + 1; it != str.end(); it++) { //预处理
*(it - 1) = (*it - *(it - 1) + 8) % 8 + '0';
}
*(str.end() - 1) = (ch - *(str.end() - 1) + 8) % 8 + '0';
//cout << str << '\n';
cout << min_Show(str) << '\n';
}
return 0;
}