本篇为个人练习记录 题目传送门
说实话,这一场的A、B让我挺难忘,尤其是B题,一开始做的时候走了弯路,浪费了很多时间。B题数据的严紧也让我感到敬佩。
A. Sweet Problem
一道典型的思维题,对三种颜色的糖果数量进行排序,如果前两个数量之和小于第三个,则答案为前两个数量之和;否则,答案为糖果数量总和的一半。
AC代码
#include <bits/stdc++.h>
using namespace std;
int t, n, ans;
int a[4];
int main() {
scanf("%d", &t);
while(t --) {
for(int i = 0; i < 3; i++) scanf("%d", &a[i]);
sort(a, a + 3);
if(a[0] + a[1] < a[2]) ans = a[0] + a[1];
else ans = (a[0] + a[1] + a[2]) >> 1;
cout << ans << '
';
}
return 0;
}
B. PIN Codes
这个是一个暴力模拟题,但也需要一点思维_。
阅读题目后,会发现每一次测试的数量在(2le nle10),也就是说,只需要改变一个位置即可。这道题目的做法是利用map
来储存出现过的数字,如果出现次数大于(1),那么就重新构造满足条件的数字。在保证输入顺序不变的条件下输出答案。
我刚开始的做法是利用set
来记录出现过的数字,而且是边输入边查询,但是这样做有问题:当你输入一个数字,构造出合法数字并标记之后,如果后面的合法数字和构造出来的数字相同,后面输入的合法数字就变成非法了,导致答案出现错误。这种情况就得用set<pair<int, int> >
了,但是和用map
没什么实质性的区别。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int n, t, x, b[N];
map<int, int> mp;
int solve(int v) {
v -= v % 10;
for(int i = 0; i <= 9; i++) if(!mp[v + i]) return v + i;
}
int main() {
scanf("%d", &t);
while(t --) {
vector<int> ans;
mp.clear();
int cnt = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &b[i]);
mp[b[i]] ++;
}
for(int i = 0; i < n; i++) {
if(mp[b[i]] > 1) {
mp[b[i]] --; int k = solve(b[i]); cnt ++;
mp[k] ++; ans.push_back(k);
} else ans.push_back(b[i]);
}
printf("%d
", cnt);
for(auto v : ans) printf("%04d
", v);
}
return 0;
}