拼多多20220903笔试题解【部分】
1.字符串转换,每次可将字符串中的一种字母减一,求不超过k次的字典序最小的装换
2.左右横跳,求每个下标跳出去的步数
3.将#变为字母,求S和T最大覆盖的情况,如果有多个S,求字典序最小的答案
4.分班考试期望得分
1.要字典序最小,那么就从头往尾计算,记录每种字符可以转换到的最小字符,注意,一开始要先统计不超过k次所能计算到的最长部分,比如ekyv,发现ek都可以变到a,于是先考虑ek,次数先减去ek中的最大变换值,再对后面的字符串进行处理
#include <bits/stdc++.h>
using namespace std;
int main() {
int T;
cin >> T;
while(T--) {
int n, k;
cin >> n >> k;
string s;
cin >> s;
unordered_map<char, char>mp;
for(char c = 'a'; c <= 'z'; c++) mp[c] = c;
int index = 0;
int max_ = 0;
for(int i = 0; i < n; i++) {
if(s[i] - 'a' <= k) {
index++;
max_ = max(max_, s[i] - 'a');//记录前面能减的那一部分,比如ekyv中的ek部分,最大是k
}
else break;
}
k -= max_;
for(int i = 0; i < index; i++) {
for(char c = 'a'; c <= s[i]; c++) mp[c] = 'a';
}
for(int i = index; i < n && k > 0; i++) {
s[i] = mp[s[i]];
int x = s[i] - 'a';
x = min(x, k);
k -= x;
for(int j = 0; j < x; j++) {
char c = s[i] - j;
mp[c] = (char)(s[i] - x);
}
}
for(int i = 0; i < n; i++) {
s[i] = mp[s[i]];
}
cout << s << endl;
}
return 0;
} #include <bits/stdc++.h>
using namespace std;
int main() {
int T;
cin >> T;
while(T--) {
int n;
cin >> n;
vector<char>s(n);
vector<long long>a(n);
for(int i = 0; i < n; i++) {
cin >> s[i] >> a[i];
}
vector<long long>ans(n);
for(int i = 0; i < n; i++) {
if(ans[i] != 0) continue;
vector<int>path;
unordered_map<int, bool>vis;//是否走过该点,判断是否成环
int now = i;
long long step = 0;
while(true) {
// cout << "now: " << now << endl;
step++;
path.push_back(now);
vis[now] = true;
if(s[now] == 'L') now -= a[now];
else now += a[now];
if(now < 0 || now >= n) break;
if(vis[now]) {
step = -1;
break;
}
if(ans[now] != 0) {
if(ans[now] == -1) step = -1;
else step += ans[now];//这个点有答案,直接加上
break;
}
}
for(int j = 0; j < path.size(); j++) {
// cout << path[j] << endl;
if(step == -1) ans[path[j]] = -1;
else ans[path[j]] = step - j;
}
}
for(int i = 0; i < n; i++) {
if(i < n - 1) cout << ans[i] << ' ';
else cout << ans[i] << endl;
}
}
return 0;
} #include <bits/stdc++.h>
using namespace std;
int main() {
string s, t;
cin >> s >> t;
int n = s.size();
if(s.size() < t.size()) {
int index = 1;
while(true) {//调试用的,最后没错,说明后台数据里没有s小于t的情况
index = index + 23;
}
cout << s << endl;
return 0;
}
vector<int>count1(26);
vector<int>count2(26);
int count3 = 0;
for(int i = 0; i < s.size(); i++) {
if(s[i] != '#') count1[s[i] - 'a']++;
else count3++;
}
for(int i = 0; i < t.size(); i++) {
count2[t[i] - 'a']++;
}
int num = 0;//先看看s可以组成多少个完整的T,并减去这么多个T
for(int i = 0; i < 26; i++) {
if(count2[i]) num = min(count1[i] / count2[i], num);
}
for(int i = 0; i < 26; i++) {
count1[i] -= num * count2[i];
}
string ans;
while(count3 > 0) {
bool flag = true;
int temp_count3 = count3;
vector<int>need(26);
for(int i = 0; i < 26; i++) {
if(count1[i] >= count2[i]) {//该字符可以由s组成
count1[i] -= count2[i];
} else if(count3 >= count2[i] - count1[i]) {//s不够了,由#来凑
count3 -= count2[i] - count1[i];
need[i] = count2[i] - count1[i];
count1[i] = 0;//这里忘记减了,卡了好久。。
} else {
flag = false;
}
}
if(!flag) {
count3 = temp_count3;
break;
}
for(int i = 0; i < 26; i++) {
while(need[i]--) {
ans.push_back((char)(i + 'a'));
}
}
}
while(count3--) {
ans.push_back('z');
}
sort(ans.begin(), ans.end());
int index = ans.size() - 1;
for(int i = 0; i < n; i++) {
if(s[i] == '#') {
s[i] = ans[index--];
}
}
cout << s << endl;
return 0;
} 4.第三题忘记减了,卡了好久,第四题就处理了下数据,求思路
查看13道真题和解析
