2024 暑假友谊赛 2
2024.7.20 9:00————12:00
过题数3/9
补题数4/9
- CodeForces 1150B
- CodeForces 1332D
- CodeForces 1503B
- AtCoder arc134_b
- AtCoder abc278_d
- AtCoder abc216_f
- CodeForces 1012B
- CodeForces 1328E
- AtCoder abc344_f
A - Tiling Challenge
题解:
给出一个n行n列的图,求是否能讲所有空白部分用一个由五个小白快组成的小十字填满。
遍历寻找,满足条件则标记。
代码:
#include<iostream>
#include<algorithm>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>using namespace std;
#define int long long
int n;
char a[55][55];signed main() {cin >> n;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cin >> a[i][j];}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {if(a[i][j] == '.' && a[i+1][j] == '.' && a[i+2][j] == '.' && a[i+1][j-1] =='.' && a[i+1][j+1]=='.'){a[i][j] = '!';a[i+1][j] = '!';a[i+2][j] = '!';a[i+1][j-1] = '!';a[i+1][j+1] = '!';}}}bool st = true;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {if(a[i][j] == '.')st=false;}}if(st)cout << "YES";else cout << "NO";return 0;
}
B - Walk on Matrix
题解:
要求输出一个二维数组,从左上角到右下角的与的结果的最大值,与dp出的最大值相差k,只能向右或向下走。
输出一个俩行三列的数组即可,使得[1][3]是0,[2][2]的值最大但[2][3]的值并不是最大,根据与的性质一一赋值即可。
代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>using namespace std;
#define int long long
int k;
int m[1005];
int b[1005];
int a[1005];
int aa,bb,mm;signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> k;int res = k;int i = 0;cout << 2 << ' ' << 3 << endl;while (res != 0) {m[i] = res%2;res = res/2;i++;}bb = pow(2,i);aa = bb-1;int ll = pow(2,i+1)-1;cout << ll << ' ' << bb << ' ' << 0 << endl;cout << aa << ' ' << ll << ' ' << k << endl;return 0;
}
D - Reserve or Reverse
题解:
给出一个长度为n的字符串s,可以在其中不连续的挑出偶数个数字,进行颠转,请输出经过操作后的最大字符串。
说一下错误思想,从前往后记录从第一位到当前位置的最小字符,如果再从后往前的过程中到了这个字符就交换,否则就不交换。反例,hwtizzzibca,由于到i位置的最小值是h,所以无法交换,但其实交换了可以变得更大。
正解,从俩边向中间以二十六个英文字母的顺序找,找到并满足条件就交换,找不到就直接找下一个字母,注意寻找区间的l,r不要动,用i,j去找。
代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>using namespace std;
#define int long long
int n;
char s[200005];signed main() {cin >> n;for (int i = 0; i < n; i++) {cin >> s[i];}for (int ch = 'a',l = 0,r = n-1; ch <= 'z' && l < r; ch++) {//这个地方注意一下,必须用int,char会报错for (int i = l,j = r; i < j; j--) {while(s[j] == ch && s[i] <= s[j] && i < j )i++;if(s[j] == ch && s[i] > s[j] && i < j) {swap(s[i],s[j]);l = i+1,r = j-1;}}}for (int i = 0; i < n; i++) cout << s[i];return 0;
}
E - All Assign Point Add
挺无语的一道题,一直tle,一直在优化然后就过了,我还以为是我方法不对。
题解:
三种操作,操作1将数组a中每个值变成x,操作2将数组a[q]加上x,操作3查询a[q]。
思路比较简单不做赘叙,注意用map储存,查询和删除复杂度都较低。
代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>using namespace std;
#define int long long
int n;
int a[200005];
int q;
int res = 0;
map<int,int>b;signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n;for (int i = 1; i <= n; i++) {cin >> a[i];}cin >> q;bool st = true;int stt = -1;while (q--) {int p;cin >> p;if(p == 1 && stt == 1) {int x;cin >> x;res = x;st = false;}else if(p == 1) {int x;cin >> x;res = x;b.clear();st = false;stt = 1;}else if(p == 2) {int j,x;cin >> j >> x;if(b.count(j) == 1) {b[j] += x;}else {b[j] = x;}stt=2;}else if(p == 3){int j;cin >> j;int ans;if(!st)ans = res;else ans = a[j];ans += b[j];cout << ans << endl;}}return 0;
}