題目
思路
貪心 暴力枚舉。
這題要求截取最少數量的字符串,使得每個字符串在所有各自的循環字符串中字典序最小。
首先,枚舉截取字符串的開始位置。
然後,枚舉截取的長度(從長到短,貪心)。
接着,截字符串。
最後判斷當前字符串是否爲字典序最小的字符串。
那麼,判斷的時候如何截取循環字符串呢?
① 先從當前位置截取到最後,再從開始截取到當前位置,將這兩段結合在一起。
結合的操作string就很好實現了。直接 即可。
實現方法:
bool judge(string s) {
string x;
int n = s.size();
for (int i = 1; i < n; i++) {
x = s.substr(i, n-i) + s.substr(0, i);
if (x < s) return false;
}
return true;
}
② 開兩倍的字符串。
比如
這裏同樣用string很好實現。
這樣就可以直接截取了。
實現方法:
bool judge(string s) {
string x;
int n = s.size();
string ss = s+s;
for (int i = 0; i < n; i++) {
x = ss.substr(i, n);
if (x < s) return false;
}
return true;
}
代碼
1:
//1
#include <bits/stdc++.h>
using namespace std;
bool judge(string s) {
string x;
int n = s.size();
for (int i = 1; i < n; i++) {
x = s.substr(i, n-i) + s.substr(0, i);
if (x < s) return false;
}
return true;
}
int main() {
int T; scanf("%d", &T);
string s, x;
while (T--) {
cin >> s;
int n = s.size();
for (int j = 0; j < n; ) {
for (int k = n - j; k >= 0; k--) {
x = s.substr(j, k);
if(judge(x)) {
cout << x << " ";
j = j + k;
break;
}
}
}
puts("");
}
return 0;
}
2:
//2
#include <bits/stdc++.h>
using namespace std;
bool judge(string s) {
string x;
int n = s.size();
string ss = s+s;
for (int i = 0; i < n; i++) {
x = ss.substr(i, n);
if (x < s) return false;
}
return true;
}
int main() {
int T; scanf("%d", &T);
string s, x;
while (T--) {
cin >> s;
int n = s.size();
for (int i = 0; i < n; )
for (int j = n - i; j >= 0; j--) {
x = s.substr(i, j);
if(judge(x)) {
cout << x << " ";
i = i + j;
break;
}
}
puts("");
}
return 0;
}