问题描述
蒜头君发现了一个很好玩的事情,他对一个数作旋转操作,把该数的最后的数字移动到最前面。比如,数 123 可以得到 312, 231,123这样就可以得到很多个数。
现在,蒜头君的问题是这些数中,有多少个不同的数小于原数,多少个等于原数,多少个大于原数。
旋转中可能会出现前导零,两数比较的时候可以忽略前导零的影响。
输入格式
输入一个整数 N(0 < N <1e100000)。
输出格式
答案在一行中输出三个整数,分别是小于 NN,等于 NN,大于 NN 的个数,中间以空格隔开。
样例输入
3 4 1
样例输出
1 1 1
AC代码
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
string num;
int n;
int tmp[200010];
int Next[200010];
void get_tmp(string s) {
tmp[0] = 0;
for (int i = 1; i < s.size(); i++) {
int j = tmp[i - 1];
while (j && s[i] != s[j]) {
j = tmp[j];
}
tmp[i] = s[i] == s[j] ? j + 1 : 0;
}
}
void get_Next(string s) {
Next[0] = s.size();
int j = 0, k = 1, t, l;
while (j + 1 < s.size() && s[j] == s[j + 1])j++;
Next[1] = j;
for (int i = 2; i < s.size(); i++) {
j = k + Next[k] - 1;
l = Next[i - k];
if (i + l - 1 < j) {
Next[i] = l;
}
else {
t = max(0, j - i + 1);
while (i + t < s.size() && s[i + t] == s[t])t++;
Next[i] = t; k = i;
}
}
}
int main() {
cin >> num;
num = num + num;
get_tmp(num);
n = num.size() / 2;
if (tmp[num.size() - 1] > n) {
n = num.size() - tmp[num.size() - 1];
}
get_Next(num);
int xiao = 0;
int deng = 1;
int da = 0;
for (int i = 0; i < n; i++) {
if (Next[i] < n) {
if (num[i + Next[i]] < num[Next[i]]) {
xiao++;
}
else {
da++;
}
}
}
cout << xiao << " " << deng << " " << da << endl;
return 0;
}