Algorithm usage
The smallest notation is a noun I saw when I was looking at the plug DP. I first looked at this algorithm. It is quite simple. There is a string connected to the first position. We need to find a position, from this position backwards To form a new string, we need to make this string lexicographically minimal.
Algorithm Explained
Here we want i = 0, j = 1, k = 0, which means that the string of k length from i is the same as the string of k length from j (i, j represent the current judgment position)
When we str[i] == str[j], according to the definition of k above, we need to perform k+1 operation
When str[i] > str[j], we find that the i position is larger than the lexicographical order of the j position, so we can't use i as the beginning. How much should we move i backward? Because there are k same characters at the beginning of i and j, then execute i = i + k +1
Conversely, when str[i] < str[j], execute: j = j + k +1
The smaller of the final i and j is where we end up starting
On the contrary, if it is the largest representation, we need to solve the string with the largest lexicographical order, then we only need to choose the larger position when performing the second or third operation.
template
int Get_min () { int n = strlen(s); int i = 0,j = 1,k = 0,t; //Indicates that the string of length k starting from i and starting from j is the same as the length of k while(i < n && j < n && k < n) { t = s[(i+k)%n] - s[(j+k)%n]; //t is used to calculate which lexicographical order is larger at the corresponding position if(!t) k++;//The case of equal characters else { if(t > 0) i += k+1;//i position is large, maximum notation: j += k+1 else j += k+1;//j position is large, maximum notation: i += k+1 if(i == j) j++; k = 0; } } return i >j ?j :i; }
Chestnut
Naked title with a minimal representation, POJ 1509
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <cstdio> using namespace std; char s[11000]; int Get_min () { int n = strlen(s); int i = 0,j = 1,k = 0,t; //Indicates that the string of length k starting from i and starting from j is the same as the length of k while(i < n && j < n && k < n) { t = s[(i+k)%n] - s[(j+k)%n]; //t is used to calculate which lexicographical order is larger at the corresponding position if(!t) k++;//The case of equal characters else { if(t > 0) i += k+1;//i position is large else j += k+1;//j position is large if(i == j) j++; k = 0; } } return i >j ?j :i; } intmain() { int n; scanf("%d",&n); for(int i = 0;i < n;i ++) { scanf("%s",s); printf("%d\n",Get_min()+1); } }