A. 辞書順最小文字列生成
解法概要
2つの文字列を降順にソートし、交互に文字を取り出す。同じ文字列から連続して取り出す回数が制限値kを超えないようにしながら、最終的に辞書順が最小になるように構築する。
変更版コード例
#include <iostream>
#include <algorithm>
using namespace std;
void process() {
int lenA, lenB, maxSame;
cin >> lenA >> lenB >> maxSame;
string strA, strB;
cin >> strA >> strB;
sort(strA.begin(), strA.end(), greater<char>());
sort(strB.begin(), strB.end(), greater<char>());
string result;
int countA = 0, countB = 0;
while (lenA > 0 && lenB > 0) {
if ((strA[lenA-1] < strB[lenB-1] && countA < maxSame) || countB >= maxSame) {
result += strA[lenA-1];
lenA--;
countA++;
countB = 0;
} else {
result += strB[lenB-1];
lenB--;
countB++;
countA = 0;
}
}
cout << result << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int testCases;
cin >> testCases;
while (testCases--) {
process();
}
return 0;
}
B. 文字列構築問題
解法概要
0と1の出現回数をバランスよく交互に配置し、残りを連続で配置する。多い方を先に開始しないように注意する。
変更版コード例
#include <iostream>
using namespace std;
void buildString() {
int counts[2];
cin >> counts[0] >> counts[1];
int major = (counts[0] > counts[1]) ? 0 : 1;
string pattern = "01";
for(int i = 0; i < counts[0] + counts[1]; i++) {
if(counts[0] > 0 && counts[1] > 0) {
cout << pattern[major];
counts[major]--;
major = 1 - major;
} else {
cout << pattern[major];
}
}
cout << endl;
}
int main() {
int cases;
cin >> cases;
while(cases--) {
buildString();
}
return 0;
}
C. ミスティック順列生成
解法概要
制約が小さいため、再帰による全探索が可能。各位置で元の順列と異なる値を選び、すべての要素が異なる順列を生成する。
変更版コード例
#include <iostream>
#include <vector>
using namespace std;
void findPermutation() {
int size;
cin >> size;
vector<int> source(size+1);
for(int i = 1; i <= size; i++) {
cin >> source[i];
}
vector<int> result(size+1, 0);
vector<int> used(size+1, 0);
bool found = false;
function<void(int)> dfs = [&](int position) {
if(found) return;
if(position == size + 1) {
found = true;
for(int i = 1; i <= size; i++) {
cout << result[i] << (i == size ? "\n" : " ");
}
return;
}
for(int i = 1; i <= size; i++) {
if(i != source[position] && !used[i]) {
result[position] = i;
used[i] = 1;
dfs(position + 1);
used[i] = 0;
}
}
};
dfs(1);
if(!found) cout << "-1\n";
}
int main() {
int cases;
cin >> cases;
while(cases--) {
findPermutation();
}
return 0;
}