五月codeforces日常训练题集
作者:互联网
\(\color{orange}{强者之路注定充满了心酸与孤独}\)
(1)2021-2022 ICPC, NERC, Northern Eurasia Onsite (Unrated, Online Mirror, ICPC Rules, Teams Preferred)-D - Deletive Editing
题意:
给定两个字符串a,b,可以对a进行任意次数的删除操作:删除某个字母在a中首次出现的位置。问能否通过该操作通过a得到b?
分析:当b中的字母顺序在a中有逆序的时候,就不能,或者a中没有b中的字母,就不能。所以要解决的就是如何去设计这样一个程序。我们可以从后往前枚举a,如果当前位置的\(a_i\)不等于\(b_j\)那么就删除掉,并且记录已经删除了,如果在i的位置之前就已经删去了\(b_j\)那么就是说在a中有逆序了,就不行。
代码:
#include <bits/stdc++.h>
using namespace std;
int cnt[30];
void solve() {
string a, b;
cin >> a >> b;
memset(cnt, 0, sizeof cnt);
int n = a.size() - 1, m = b.size();
for(int i = m - 1; i >= 0; i--) {
if(cnt[b[i] - 'A']) {
puts("NO");
return;
}
while(n >= 0 && a[n] != b[i]) {
cnt[a[n] - 'A'] = 1;
n--;
}
if(n < 0) {
puts("NO");
return;
}
n--;
}
puts("YES");
}
int main(){
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
(2)Educational Codeforces Round 124 (Rated for Div. 2)-B. Prove Him Wrong
题意:
给定一个数n,证明是否存在这样的一个数组,长度为n并且对任意的2*|\(a_i\) - \(a_j\)| >= \(a_i\) + \(a_j\)。如果存在 输出任意符合要求的数组。
思路:根据得出的关系,假设\(a_i\) > \(a_j\) 则可推出公式:$$ a_i >= 3 * a_j$$ 所以数组从小到大最小是呈3倍增长的关系即$$ 3 * a_i = a_{i+1}$$,那么1 <= \(a_i\) <= 109,只需要计算3的多少次方最接近109,超过这个数就不存在。这个数为19;
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define x first
#define y second
typedef pair<int,int>PII;
const int N = 2e5 + 10;
int cnt[30];
void solve() {
int n;
cin >> n;
if(n > 19) {
cout << "NO" << endl;
return;
}
int t = 1;
cout << "YES" << endl;
while(n) {
cout << t << ' ';
t *= 3;
n--;
}
cout << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
(3)Educational Codeforces Round 124 (Rated for Div. 2)-A - Playoff
题意:
给定一个数n,代表有2^n个球员,获胜的条件是:如果x和y对决,如果x+y是奇数,那么数字小的获胜,如果是偶数,则数字大的获胜。第一轮:[1,2]决出胜者,[3,4]决出胜者... 第二轮[1,3][5,7]...决出胜者,问给定n,最后的胜者是谁?
思路:
通过模拟发现,第一轮过后,所有的偶数都将被淘汰,剩下的全是奇数,也就是说从第二轮开始两两对决一定是数字大获胜。那么到最后一定是所有奇数最大的获胜。所以是2^n - 1。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define x first
#define y second
typedef pair<int,int>PII;
const int N = 2e5 + 10;
int cnt[30];
void solve() {
int n;
cin >> n;
cout << (1 << n) - 1 << endl;
}
signed main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
(4)Codeforces Round #777 (Div. 2)-C. Madoka and Childish Pranks
题意:
给定一个初始全是0的棋盘,再给定一个目标棋盘,可以进行一个操作:将一个矩阵(规模大于1)染成:横纵坐标之和为偶数 则染成0,否则染成1,并且左上角必须是0。问从初始到目标的操作数可以是多少(并没有要求最小!)。
思路:从右下到左上依次枚举。但是如果整个目标棋盘的左上角为1,则无法达到。如果纵坐标不为1,则都可以通过水平规模为21的矩阵得到,否则只能通过竖直的规模为12的矩阵得到,分别存一下前后两个点的坐标即可。最后输出。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
char a[N][N];
struct node {
int x1, y1, x2, y2;
}cnt[N*N];
void solve() {
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> a[i][j];
if(a[1][1] == '1') {
cout << -1 << endl;
return;
}
int k = 0;
for(int i = n; i; i--)
for(int j = m; j; j--) {
if(a[i][j] == '0') continue;
if(j != 1) {
cnt[k].x1 = i, cnt[k].y1 = j - 1, cnt[k].x2 = i, cnt[k].y2 = j;
k++;
}else {
cnt[k].x1 = i - 1, cnt[k].y1 = j, cnt[k].x2 = i, cnt[k].y2 = j;
k++;
}
}
cout << k << endl;
for(int i = 0; i < k; i++) cout << cnt[i].x1 << ' ' << cnt[i].y1 << ' ' << cnt[i].x2 << ' ' << cnt[i].y2 << endl;
}
int main() {
int t;
cin >> t;
while(t--) {
solve();
}
return 0;
}
标签:cnt,return,int,题集,codeforces,--,solve,五月,define 来源: https://www.cnblogs.com/MoonSkyy/p/16251761.html