A phone desktop
问题:
思路:贪心,先排2x2 再排1x1,2x2的数量决定了ans的下限,1x1的数量决定了上限,最后输出两个值的max
代码:
#include <iostream>
using namespace std;
int a, b;
void solve() {
cin >> b >> a;
cout << max((a + 1) / 2, (b + a * 4 + 14) / 15) << endl;
}
int main() {
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
B Symmetric Encoding
问题:
思路:将给定字符串排序去重,映射回去即可
代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
char str[N];
int n;
void solve() {
cin >> n;
vector<char> a;
for(int i = 1; i <= n; i ++ ) {
cin >> str[i];
a.push_back(str[i]);
}
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
int s = a.size() - 1;
for(int i = 1; i <= n; i ++ ) {
char c = str[i];
int pos = 0;
for(int j = 0; j <= s; j ++ ) {
if(a[j] == c) {
pos = j;
break;
}
}
cout << a[s - pos];
}
cout << endl;
}
int main() {
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
C Beautiful Triple Pairs
问题:
思路:容斥原理
代码:
#include <iostream>
#include <map>
using namespace std;
const int N = 2e5 + 10;
int a[N];
int n;
void solve() {
cin >> n;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
long long ans = 0;
for(int i = 0; i < 3; i ++ ) {
for(int j = i + 1; j < 3; j ++ ) {
map<pair<int, int>, int> ma;
for(int k = 1; k <= n - 2; k ++ ) {
ans += ma[{a[k + i], a[k + j]}];
ma[{a[k + i], a[k + j]}] ++;
}
}
}
map<tuple<int, int, int>, int> ma;
for(int i = 1; i <= n - 2; i ++ ) {
ans -= 3 * ma[{a[i], a[i + 1], a[i + 2]}];
ma[{a[i], a[i + 1], a[i + 2]}] ++;
}
cout << ans << endl;
}
int main() {
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
D ingenuity - 2
问题:
思路:分别考虑竖直方向水平方向,以水平方向为例,出现ew可以抵消,若最后剩下的e或者w为偶数个则合法,另外还要判断H,R是否执行了至少一条指令例如WE这个条件是非法的,原因是肯定有一个机器无法执行命令。这里代码写的很繁琐,写完比赛就结束了,抽时间改一下
代码:
#include <iostream>
#include <vector>
#include <map>
using namespace std;
const int N = 2e5 + 10;
int n;
char str[N];
void solve() {
map<char, int> ma;
cin >> n;
vector<char> ans(n + 1, 'q');
for(int i = 1; i <= n; i ++ ) {
cin >> str[i];
ma[str[i]] ++;
}
char maxc1, minc1, maxc2, minc2;
if(ma['N'] > ma['S']) {
maxc1 = 'N';
minc1 = 'S';
} else {
maxc1 = 'S';
minc1 = 'N';
}
if(ma['E'] > ma['W']) {
maxc2 = 'E';
minc2 = 'W';
} else {
maxc2 = 'W';
minc2 = 'E';
}
if((ma[maxc1] - ma[minc1]) % 2 || (ma[maxc2] - ma[minc2]) % 2) {
cout << "NO" << endl;
return;
}//方案不合法
if(ma[maxc1] == ma[minc1] && ma[maxc2] == ma[minc2] && ma[minc1] + ma[minc2] <= 1) {
cout << "NO" << endl;
return;
}
int cntmaxc1 = ma[minc1] + (ma[maxc1] - ma[minc1]) / 2;
int cntmaxc2 = ma[minc2] + (ma[maxc2] - ma[minc2]) / 2;
bool flag = true;
if(flag && ma[maxc1] == ma[minc1] && ma[maxc1] != 0) {
// cntmaxc1 --;
bool flagma = 1, flagmin = 1;
for(int i = 1; i <= n; i ++ ) {
if(flagma && str[i] == maxc1) {
ans[i] = 'H';
flagma = 0;
}
if(flagmin && str[i] == minc1) {
ans[i] = 'H';
flagmin = 0;
}
}
flag = false;
}
if(flag && ma[maxc2] == ma[minc2] && ma[maxc2] != 0) {
//cntmaxc2 --;
bool flagma = true, flagmin = true;
for(int i = 1; i <= n; i ++ ) {
if(flagma && (str[i] == maxc2)) {
ans[i] = 'H';
flagma = false;
}
if(flagmin && str[i] == minc2) {
ans[i] = 'H';
flagmin = false;
}
}
flag = false;
}
if(flag && ma[maxc1] != ma[minc1]) {
//cntmaxc1 --;
for(int i = 1; i <= n; i ++ ) {
if(str[i] == maxc1) {
ans[i] = 'H';
break;
}
}
flag = false;
}
if(flag && ma[maxc2] != ma[minc2]) {
//cntmaxc2 --;
for(int i = 1; i <= n; i ++ ) {
if(str[i] == maxc2) {
ans[i] = 'H';
break;
}
}
flag = false;
}
for(int i = 1; i <= n; i ++ ) {
if(ans[i] == 'q') {
if(str[i] == 'N' || str[i] == 'S') {
if(str[i] == minc1) {
ans[i] = 'R';
} else {
if(cntmaxc1) {
cntmaxc1 --;
ans[i] = 'R';
} else ans[i] = 'H';
}
} else {
if(str[i] == minc2) {
ans[i] = 'R';
} else {
if(cntmaxc2) {
cntmaxc2 --;
ans[i] = 'R';
} else ans[i] = 'H';
}
}
}
}
for(int i = 1; i <= n; i ++ ) cout << ans[i];
cout << endl;
/*cout << ma['W'] << " " << ma['E'];
cout << maxc2 << minc2;*/
}
int main() {
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
E money buy less happy
问题:
思路:背包,dp[i]表示当前happy值为i,可以拥有的最大钱数,从大到小枚举是为了让状态转移时用已经搜过的状态转移,最开始把不可能的状态置负无穷dp[0]置0,这样搜出来的方案一定是可以实现的,dp时每个月记得加上工资
代码:
#include <iostream>
#include <vector>
using namespace std;
const int N = 55;
int n, x;
int cost[N], happy[N];
void solve() {
cin >> n >> x;
int sum = 0;
for(int i = 1; i <= n; i ++ ) {
cin >> cost[i] >> happy[i];
sum += happy[i];
}
vector<long long> dp(sum + 1, -1e17);
dp[0] = 0;
for(int day = 1; day <= n; day ++ ) {
for(int i = sum; i >= 0; i -- ) {
if((i - happy[day] >= 0) && (dp[i - happy[day]] - cost[day] >= 0)) {
dp[i] = max(dp[i], dp[i - happy[day]] - cost[day]);
}
dp[i] += x;//工资
}
}
for(int i = sum; i >= 0; i -- )
if(dp[i] >= 0) {
cout << i << endl;
return;
}
}
int main() {
int t;
cin >> t;
while(t -- ) {
solve();
}
}
F cutting game
题目:
思路:思路源于b站幻想家协会会长,离线做法+二维二分,对二分的顶级理解,这是我目前为止看到的最简洁的做法
代码:
#include <iostream>
using namespace std;
const int N = 2e5 + 10;
int a, b, n, m;
struct node{
int x1, y1, x2, y2;
}d[N];
pair<int, int> pos[N];
void solve() {
cin >> a >> b >> n >> m;
for(int i = 1; i <= n; i ++ ) {
int x, y;
cin >> x >> y;
pos[i] = {x, y};
}
int x1, y1, x2, y2;
x1 = 1, y1 = 1, x2 = a, y2 = b;
//cout << x1 << " " << y1 << " " << x2 << " " << y2 << endl;
for(int i = 1; i <= m; i ++ ) {
char op;
int x;
cin >> op >> x;
if(op == 'U') {
x1 += x;
d[i] = {x1, y1, x2, y2};
} else if(op == 'D') {
x2 -= x;
d[i] = {x1, y1, x2, y2};
} else if(op == 'L') {
y1 += x;
d[i] = {x1, y1, x2, y2};
} else {
y2 -= x;
d[i] = {x1, y1, x2, y2};
}
}
int scoreA = 0, scoreB = 0;
for(int i = 1; i <= n; i ++ ) {
int x = pos[i].first, y = pos[i].second;
int l = 1, r = m + 1;
while(l < r) {
int mid = l + r >> 1;
if(x < d[mid].x1 || x > d[mid].x2 || y < d[mid].y1 || y > d[mid].y2) r = mid;
else l = mid + 1;
}
if(l != m + 1) {
if(l & 1) scoreA ++;
else scoreB ++;
}
}
cout << scoreA << " " << scoreB << endl;
}
int main() {
int t;
cin >> t;
while(t -- ) {
solve();
}
return 0;
}
G money buys less happiness now
问题:
思路:贪心。
代码:
#include <iostream>
#include <queue>
using namespace std;
const int N = 2e5 + 10;
int m, x;
int cost[N];
void solve() {
priority_queue<int> q;
cin >> m >> x;
for(int i = 1; i <= m; i ++ ) cin >> cost[i];
long long salary = 0;
for(int i = 1; i <= m; i ++ ) {
q.push(cost[i]);
salary -= cost[i];
while(salary < 0) {
salary += q.top();
q.pop();
}
salary += x;
}
cout << q.size() << endl;
}
int main() {
int t;
cin >> t;
while(t -- ) {
solve();
}
}