sgu232(最小表示法)

2021-08-07 08:21:34 字數 1501 閱讀 6938

給出n,m,以及長度為n的原字串s[0,n-1]。根據s構造出新的n個字串a[n],a[i][j]=s[(i+j*m)%n]。求a中最大的串。

嘗試nm之後 可以發現a每n次開始迴圈(mod後和之前的迴圈節是同樣的幾個數,可能不到n),每次由於是取mod 所以也是有迴圈節的,那麼找出這個迴圈節,找到迴圈同構中最大的(左移或右移任意位)就可以。。。

最小表示法:

例如,字串」abcd」的迴圈同構字串有:[「abcd」, 「bcda」, 「cdab」, 「dabc」]。

題目的目標是求這些字串中字典序最小的那個 演算法描述 :

令i=0,j=1

如果s[i] > s[j] i=j, j=i+1

如果s[i] < s[j] j++

如果s[i] == s[j] 設指標k,分別從i和j位置向下比較,直到s[i] != s[j]

如果s[i+k] > s[j+k] i+= k+1 ,k = 0,//(j變為標準)

否則 j+=k+1,k = 0

//(i仍是標準)

if(i == j)j++;

返回min(i,j)

類似雙支針,一直保留較小的乙個。。比較好理解,最大表示除了比較的大於小於變一下就好了

int maxrp(string s)

else

if(l == r) r++;

}return min(l,r);

}

整個題的**:

#include 

#include

#include

#include

using

namespace

std;

string s,ans = "";

const

int maxn = 150010;

int len,vis[maxn];

int n,m;

void init()

int maxrp(string s)

else

if(l == r) r++;

}return min(l,r);

}void sov()

int pos = maxrp(tmp),len = tmp.length();

tmp += tmp;

string pp = tmp.substr(pos,len);

if(ans == "" || ans < pp) ans = pp;

}string nn = "";

int k = ans.length();

int rp = n/k;

for(int i = 1; i <= rp ; i++)

nn += ans;

int mo = n-nn.length();

nn = nn+nn.substr(0,mo);

cout

最小表示法

最小表示法就是找出字串s的的迴圈同構串中字典序最小的乙個。那麼什麼是迴圈同構串呢。是 設s bcad 且s 是s 的迴圈同構的串。s 可以是 bcad 或者cadb,adbc,dbca 即在字串s中從i 0開始,從i迴圈到字串末尾,再從頭迴圈到i,所形成的字元就是s迴圈同構串。因為這樣的同構串不止乙...

最小表示法

最小表示法 思想 在字串迴圈同構問題中的應用 摘自周源的ppt 前言 最小表示法 比起動態規劃 貪心等思想,在當今競賽中似乎並不是很常見。但是在解決判斷 同構 一類問題中卻起著重要的作用。本文即將討論字串中的同構問題,如何巧妙地運用最小表示法來解題呢,讓我們繼續一起思考吧。到底什麼是迴圈同構的字串呢...

最小表示法

最小表示法與kmp演算法一樣都可以解決字串匹配問題,但效率更高,短,作用更大。最小表示法就是乙個字串的最小字典序。怎麼求乙個字串的最小字典序呢?首先將這個字串擴充套件一倍 建設存在d陣列裡 然後我們用三個指標i 0,j 1,k 0,來尋找最小字典序的開頭字母,為了優於kmp,我們要做到o n i表示...