Codeforces Round 742 Div2 A-D题解
Codeforces Round 742 Div2 A-D题解
A. Domino Disaster
这题就是说给出一些2x1 tile,然后给出2xn的第一行构造,问第二行
这个刚开始想着是啥dp,一看那么多人过了果断改思路,发现这题就是个模拟题,就是把U换成D,D换成U,L和R不影响,然后输出就行了
代码
#include <bits/stdc++.h>
using namespace std;
constexpr int limit = (2e5 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
ll sign = 1, x = 0;
char s = getchar();
while (s > '9' || s < '0') {
if (s == '-')sign = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * sign;
#undef getchar
}//快读
void print(ll x) {
if (x / 10) print(x / 10);
*O++ = x % 10 + '0';
}
void write(ll x, char c = 't') {
if (x < 0)putchar('-'), x = -x;
print(x);
if (!isalpha(c))*O++ = c;
fwrite(obuf, O - obuf, 1, stdout);
O = obuf;
}
int n, m;
int a[limit];
void solve() {
cin>>n;
string str;
cin>>str;
str = " " + str;
string ans;
rep(i,1,n){
char c;
if(str[i] == 'L'){
c = 'L';
}
if(str[i] == 'R'){
c = 'R';
}
if(str[i] == 'U'){
c = 'D';
}
if(str[i] == 'D'){
c = 'U';
}
ans += c;
}
cout<<ans<<endl;
}
int32_t main() {
#ifdef LOCAL
FOPEN;
// FOUT;
#endif
FASTIO
int kase;
cin>>kase;
while (kase--)
invoke(solve);
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s";
return 0;
}
B. MEXor Mixup
这个题思路很好想,就是有些trick,首先出现要出现mex我们至少要有mex - 1个数字。 然后我们需要讨论一下mex - 1个能否满足。什么情况下能够满足?
因为xor的前缀和和交换律性质,所以我们如果mex - 1个数字bitxor前缀和等于pb,我们直接就满足了。如果不满足,那么我们可以用b bitxor一下mex - 1的前缀和就好了,所以分别是 + 1 和 + 2
代码
#include <bits/stdc++.h>
using namespace std;
constexpr int limit = (3e5 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
ll sign = 1, x = 0;
char s = getchar();
while (s > '9' || s < '0') {
if (s == '-')sign = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * sign;
#undef getchar
}//快读
void print(ll x) {
if (x / 10) print(x / 10);
*O++ = x % 10 + '0';
}
void write(ll x, char c = 't') {
if (x < 0)putchar('-'), x = -x;
print(x);
if (!isalpha(c))*O++ = c;
fwrite(obuf, O - obuf, 1, stdout);
O = obuf;
}
int n, m;
int a[limit];
// 0 1 2 3
void solve() {
int pa, pb;
cin>>pa>>pb;
ll ans = pa + 1;
if(pa > 0){
if(a[pa - 1] == pb){ // 如果pa - 1刚好是,那么只需要pa个
cout<<ans - 1<<endl;
return;
}
}
if((pb ^ a[pa - 1]) == pa){
ans++;
}
cout<<ans<<endl;
}
int32_t main() {
#ifdef LOCAL
FOPEN;
// FOUT;
#endif
FASTIO
rep(i,1,3e5){
a[i] = i ^ a[i - 1];
}
int kase;
cin>>kase;
while (kase--)
invoke(solve);
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s";
return 0;
}
思路不集中,所以写了不少时间
C. Carrying Conundrum
这题是做加法,然后进位不是相邻位置进位,而是隔着两位进位,问给出一个数字有多少ordered pair在错误条件下加起来等于这个数字。
首先我们观察到,隔一位进位,只和前两位有关系,让我们想到马尔可夫链。
然后我们可以dp出来每个地方进位 + 不进位的情况,其实后面意识到这个过程是求奇数和偶数上的方案数,哎昨天看了那个交互题说要对奇偶性敏感,自己还是不太敏感。然后找了stack overflow上一个很有意思的题目的一个类似解法。把奇偶位置上的方案数 + 1代表全是0的情况,然后相乘, -2去除有一半是0的情况就行了。
代码
#include <bits/stdc++.h>
using namespace std;
constexpr int limit = (3e5 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
ll sign = 1, x = 0;
char s = getchar();
while (s > '9' || s < '0') {
if (s == '-')sign = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * sign;
#undef getchar
}//快读
void print(ll x) {
if (x / 10) print(x / 10);
*O++ = x % 10 + '0';
}
void write(ll x, char c = 't') {
if (x < 0)putchar('-'), x = -x;
print(x);
if (!isalpha(c))*O++ = c;
fwrite(obuf, O - obuf, 1, stdout);
O = obuf;
}
int n, m;
int a[limit];
// 0 1 2 3
int dp[15]; // 代表第i位是j的是否carry
void solve() {
cin>>n;
string str = to_string(n);
// reverse(str.begin(), str.end()); //先反转
n = str.length();
str = " " + str;
ll ans = 0;
auto st = str | ranges::views::transform([](char c) { if(c == ' ') return 0; return c - '0'; });
auto get_plan = [](ll x){
ll ans = 0;
rep(i,0,10){
rep(j,i, 10){
if(i + j == x)ans++;
}
}
return ans / 2;
};
auto get_big_plan = [](ll x){
ll ans = 0;
rep(i,0,10){
rep(j,0,10){
if(i + j >= 10 and (i + j) % 10 == x){
ans++;
}
}
}
return ans / 2;
};
// for(auto it : st){
// cout<<it;
// }
// cout<<endl;
memset(dp, 0, sizeof dp);
dp[1] = st[1];
dp[2] = st[2];
rep(i,3,n){
int x = st[i];
dp[i] = dp[i - 2] * 10 + st[i];
}
ll res = dp[n];
res++;
res *= dp[n - 1] + 1;
res -= 2; //special case
cout<<res<<endl;
}
int32_t main() {
#ifdef LOCAL
FOPEN;
// FOUT;
#endif
FASTIO
rep(i,1,3e5){
a[i] = i ^ a[i - 1];
}
int kase;
cin>>kase;
while (kase--)
invoke(solve);
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s";
return 0;
}
D. Expression Evaluation Error
这题是给出一个和s,拆成n个正整数,要求11进制下和最大。
首先我们枚举一下11 - 10进制映射,然后然后我们发现,在11进制末尾位9 - 0的变化中,我们的10进制加了2,如果有更多的后缀0那么收益更大,所以我们想到先贪心。
然后写了一版除了不够的放1,其他平均分10的,不对,发现100的收益比拆成若干个10更大,后缀0位置上的数字对于答案的收益和两个数字单独拿出来是一样的。所以我们贪心地选择当前后缀0长度最大的那个进行拆分,最后拆不动了全放在第n位上就好。
可惜,这题vp的时候wa了4发才发现是我忘记删第一版代码导致的。吐了
代码
#include <bits/stdc++.h>
using namespace std;
constexpr int limit = (3e5 + 5);//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-9
#define FASTIO ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
#define pi(a, b) pair<a,b>
#define rep(i, a, b) for(ll i = a; i <= b ; ++i)
#define per(i, a, b) for(ll i = b ; i >= a ; --i)
#define MOD 998244353
#define traverse(u) for(int i = head[u]; ~i ; i = edge[i].next)
#define FOPEN freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\data.txt", "rt", stdin)
#define FOUT freopen("C:\\Users\\tiany\\CLionProjects\\akioi\\dabiao.txt", "wt", stdout)
typedef long long ll;
typedef unsigned long long ull;
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
inline ll read() {
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
ll sign = 1, x = 0;
char s = getchar();
while (s > '9' || s < '0') {
if (s == '-')sign = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = (x << 3) + (x << 1) + s - '0';
s = getchar();
}
return x * sign;
#undef getchar
}//快读
void print(ll x) {
if (x / 10) print(x / 10);
*O++ = x % 10 + '0';
}
void write(ll x, char c = 't') {
if (x < 0)putchar('-'), x = -x;
print(x);
if (!isalpha(c))*O++ = c;
fwrite(obuf, O - obuf, 1, stdout);
O = obuf;
}
#define int ll
int n, m;
ll a[limit];
void solve() {
ll s;
cin>>s>>n;
rep(i,1,n) a[i] = 0;
ll num[] = {1ll, 10ll, 100ll, 1000ll, 10000ll, 100000ll, 1000000ll, 10000000ll, 100000000ll, 100000000ll};
rep(i,1,n){
// 现在安排到第几位了
ll cur = 1;
ll rem = n - i;
for(auto it : num | views::reverse){
if(s >= it and it + rem <= s){
cur = it;
break;
}
}
s -= cur;
a[i] += cur;
}
a[n] += s;
rep(i,1,n){
cout<<a[i]<<" ";
}
cout<<endl;
}
int32_t main() {
#ifdef LOCAL
FOPEN;
// FOUT;
#endif
FASTIO
rep(i,1,3e5){
a[i] = i ^ a[i - 1];
}
int kase;
cin>>kase;
while (kase--)
invoke(solve);
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "s";
return 0;
}
总结
稳中向好吧,工作还在搞,不过感觉经过两三周的康复训练,今天明显思路快了很多,第一次一眼出D的思路,不过开始的时候还是卡卡的。这个月还得加油才行呢。