zcmu 1550( 字串的最小表示法)

2021-10-14 21:39:44 字數 1244 閱讀 7067

給你你個字串s,他可以迴圈左移,問最少左移幾次之後的字串字典序最小。

迴圈左移,比如s是(adac)那麼左移可以是adac,daca,acad,cada。這裡字典序最小是acad,那麼需要左移3次。

o(n^2)會超時,這裡介紹一種o(n)的做法

i,j是兩個指標,表示兩個字串首字母位置。k表示兩個字串最長公共字首長度,由於兩個陣列需要比較字典序,所以i,j不能相同,另i初始化為0,j初始化為1,k初始化為0

當s[i+k] == s[j+k]的時候,k作為公共字首長度就要加1。

當s[i+k] > s[j+k]的時候,i就要跳k+1下,到達i+k+1的位置

當s[i+k] < s[j+k]的時候,j就要跳k+1下,到達j+k+1的位置,為什麼呢?

我們要注意的是,在這裡,作為乙個最小字典序的串,那麼肯定有從s[i+1到j-1]開始的長度一樣的字串都不小於從s[i]開始的,不然i早就跳到後面去了,那麼如果s[i+k]>s[j+k],那麼表明下標從j開始的長度為k的字串字典序較小,

那麼i需要調整,由於j開始的字串長度為k,那麼從i開始之後的k個位置都不需要跑了,因為都不會小於當前從j開始的字串,因此i只好跳k+1個位置. 如果s[i+k]然後為了確保i和j不能相同,需要判斷一下,如果相同的話,我們讓j++,最後從i開始的長度為n的字串字典序一定最小.

#includeusing namespace std;

#define ll long long

const int maxn = 3e5 + 5;

char s[maxn];

int cal(int n)

}return i;

}int main()

return 0;

}

另外乙個類似的題p1368 【模板】最小表示法

方法可以說是一模一樣了,但他是輸出那個字典序最小的串

#includeusing namespace std;

#define ll long long

const int maxn = 3e5 + 5;

int s[maxn];

int cal(int n)

}return i;

}int main()

int ans = cal(n);

for(int i = 0; i < n; i ++)

puts("");

return 0;

}

zcmu 1839 字串對比

給定兩個僅由大寫字母或小寫字母組成的字串 長度介於1到10之間 它們之間的關係是以下4中情況之一 1 兩個字串長度不等。比如 beijing 和 hebei 2 兩個字串不僅長度相等,而且相應位置上的字元完全一致 區分大小寫 比如 beijing 和 beijing 3 兩個字串長度相等,相應位置上...

ZCMU 4944 字串處理

下午打了一場icpc的區域賽,感覺字串的練習還是不夠,晚上找了到細節字串題目來練練手,特此記錄 zcmu 4944 4944 字串處理 time limit 1 sec memory limit 32 mb submit 153 solved 65 submit status web board d...

字串1 字串的旋轉

題目描述 給定乙個字串,要求將字串前面的若干個字元移到字串的尾部。例如 將字串 abcdef 的前三個字元 a b c 移到字串的尾部,那麼原字串將變成 defabc 首先想到的是將需要移動的字元乙個乙個移到字串的尾部。實現如下 public class transfet s n 1 t publi...