HDU 3374 String Problem (KMP+最大最小表示法)
题意:输出目标字符串最小表示的下标和数量,最大表示的下标和数量
题解:最大最小表示法模板题,数量也好求,用KMP的next数组求循环节即可(字符串循环节)
#include<cstring> #include<cstdio> using namespace std; const int maxn=1000010; char s[maxn]; int nx[maxn]; void getNext(char * p) { nx[0] = -1; int i = 0, j = -1; int len=strlen(p); while (i < len) { if (j == -1 || p[i] == p[j]) { ++i; ++j; nx[i] = j; } else j = nx[j]; } } int getMin(char *s) { int i = 0, j = 1, l; int len = strlen(s); while(i < len && j < len) { for(l = 0; l < len; l++) if(s[(i + l) % len] != s[(j + l) % len]) break; if(l >= len) break; if(s[(i + l) % len] > s[(j + l) % len]) { if(i + l + 1 > j) i = i + l + 1; else i = j + 1; } else if(j + l + 1 > i) j = j + l + 1; else j = i + 1; } return i < j ? i : j; } int getMax(char *s) { int len = strlen(s); int i = 0, j = 1, k = 0; while(i < len && j < len && k < len) { int t = s[(i+k)%len]-s[(j+k)%len]; if(!t) k++; else { if(t > 0) { if(j+k+1 > i) j = j+k+1; else j = i+1; } else if(i+k+1 > j) i = i+k+1; else i = j+1; k = 0; } } return i < j ? i : j; } int main() { while(~scanf("%s",s)) { getNext(s); int len=strlen(s); int ans=len%(len-nx[len])?1:len/(len-nx[len]); printf("%d %d %d %d\n",getMin(s)+1,ans,getMax(s)+1,ans); } return 0; }

浙公网安备 33010602011771号