1. 程式人生 > >Bazinga(HDU5510+KMP)

Bazinga(HDU5510+KMP)

mat void pri set div 最大的 scanf bre n)

t題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5510

題目:

技術分享圖片

技術分享圖片

技術分享圖片

題意:找到一個編號最大的字符串滿足:存在一個編號比它小的字符串不是它的字串。

思路:KMP。但是這題的復雜度大致為1e8,杭電服務器跑穩T,我還試了一發-_-||。想了很久想到一個玄學優化,我們首先比較相鄰的兩個字符串,假設為i和i-1,且i-1是i的字串,那麽如果某個大編號包含i則必然包含i-1,此時就沒有必要再和i-1跑一邊KMP了。如下圖所示:

技術分享圖片

代碼實現如下:

 1 #include <set>
 2 #include <map>
 3
#include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14
using namespace std; 15 16 typedef long long ll; 17 typedef pair<ll, ll> pll; 18 typedef pair<ll, int> pli; 19 typedef pair<int, ll> pil;; 20 typedef pair<int, int> pii; 21 typedef unsigned long long ull; 22 23 #define lson i<<1 24 #define rson i<<1|1 25
#define bug printf("*********\n"); 26 #define FIN freopen("D://code//in.txt", "r", stdin); 27 #define debug(x) cout<<"["<<x<<"]" <<endl; 28 #define IO ios::sync_with_stdio(false),cin.tie(0); 29 30 const double eps = 1e-8; 31 const int mod = 10007; 32 const int maxn = 2000 + 7; 33 const double pi = acos(-1); 34 const int inf = 0x3f3f3f3f; 35 const ll INF = 0x3f3f3f3f3f3f3f; 36 37 int t, n; 38 int nex[507][maxn], len[507], vis[507]; 39 char s[507][maxn]; 40 41 void get_next(int x) { 42 nex[x][1] = 0; 43 for(int i = 2, j = 0; i <= len[i]; i++) { 44 while(j > 0 && s[x][i] != s[x][j+1]) j = nex[x][j]; 45 if(s[x][i] == s[x][j+1]) j++; 46 nex[x][i] = j; 47 } 48 } 49 50 bool kmp(int x, int y) { 51 for(int i = 1, j = 0; i <= len[x]; i++) { 52 while(j > 0 && (j == len[y] || s[x][i] != s[y][j+1])) j = nex[y][j]; 53 if(s[x][i] == s[y][j+1]) j++; 54 if(j == len[y]) { 55 return true; 56 } 57 } 58 return false; 59 } 60 61 int main() { 62 //FIN; 63 scanf("%d", &t); 64 int icase = 0; 65 while(t--) { 66 scanf("%d", &n); 67 memset(vis, 0, sizeof(vis)); 68 for(int i = 1; i <= n; i++) { 69 scanf("%s", s[i] + 1); 70 len[i] = strlen(s[i] + 1); 71 get_next(i); 72 } 73 int flag = 1; 74 for(int i = n; i >= 2; i--) { 75 if(kmp(i, i-1)) { 76 vis[i-1] = 1; 77 } 78 } 79 for(int i = n; i >= 2; i--) { 80 for(int j = i - 1; j >= 1; j--) { 81 if(!vis[j] && !kmp(i, j)) { 82 flag = i; 83 break; 84 } 85 } 86 if(flag != 1) break; 87 } 88 printf("Case #%d: ", ++icase); 89 if(flag != 1) printf("%d\n", flag); 90 else printf("-1\n"); 91 } 92 return 0; 93 }

Bazinga(HDU5510+KMP)