题目链接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;
}