給出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表示...