uvalive 5734 字符串最小表示法
题意:其实这道题读懂了就可以A,首先给你一个字符串,然后叫你算出这个字符串每一位的距离,得到一个新的字符串,然后把这个字符串用最小表示法表示出来。
所谓的最小表示法就是个循环左移或者右移这个字符串,使得他的字典序最小。
可以看这篇博客:http://www.cnblogs.com/ACAC/archive/2010/05/23/1742349.html
知道了这个,那么这道题就是大水题了。
比赛的时候没看懂,真是拙计。
#include <set>#include <map>#include <stack>#include <cmath>#include <queue>#include <cstdio>#include <string>#include <vector>#include <iomanip>#include <cstring>#include <iostream>#include <algorithm>#define Max 2505#define FI first#define SE second#define ll long long#define PI acos(-1.0)#define inf 0x3fffffff#define LL(x) ( x << 1 )#define bug puts("here")#define PII pair<int,int>#define RR(x) ( x << 1 | 1 )#define mp(a,b) make_pair(a,b)#define mem(a,b) memset(a,b,sizeof(a))#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )using namespace std;#define N 301111int fk[10][10] ;char Try[N] ;int now[N] ;int b[N] ;int minP(int *str){ int l = strlen(Try) ; int i = 0 , j = 1 , k = 0 ; while(1){ if(i + k >= l || j + k >= l)break ; if(str[i + k] == str[j + k]){ k ++ ; continue ; } else { if(str[j + k] > str[i + k])j += k + 1 ; else i += k + 1 ; k = 0 ; if(i == j)j ++ ; } } return min(i , j) ;}int main() { for (int i = 0 ; i <= 7 ; i ++ )fk[i][i] = 0 ; for (int i = 0 ; i <= 7 ; i ++ ) for (int j = i + 1 ; j <= 7 ; j ++ ){ fk[i][j] = (j - i) ; fk[j][i] = 8 - fk[i][j] ; } while(cin >> Try){ int l = strlen(Try) ; for (int i = 0 ; i < l - 1 ; i ++ ){ now[i] = fk[Try[i] - '0'][Try[i + 1] - '0'] ; } now[l - 1] = fk[Try[l - 1] - '0'][Try[0] - '0'] ; int ffk = minP(now) ; for (int i = 0 ; i < l ; i ++ ) printf("%d",now[(i + ffk) % l]) ; cout << endl; } return 0 ;}