前言:
昨天打了div2感觉成果还是满丧的速aT1,但是卡在了T2赛后知道原来是题目读错了,把所有value的XOR读成了任意两个
value的XOR的值,然后马上转到奇数和偶数和0异或都是这个数本身然后在错误的路上一去不返,然后看着AC赛后到达了
9k,感觉心态有点崩,今天发现了读题错误,然后又重新写了一遍(参考了Tutorial(en))还是感觉有点数学成分的存在,
感觉比赛读对题的情况下还是会卡比较久,需要好好反思总结,然后T3感觉还是比较容易的,将数转化为2个正常数的加法
然后((数一+1)*(数二+1)-2)就能a掉了(下面会写原理),T4马上能看出是个贪心问题,但是贪了三个方向,都是在其他地方
存在的缺陷,后来借助dl的提交记录然后理解发现dl的思路非常的巧妙简便,同时写下理解便于加深记忆.
A. Domino Disaster
思路
一题水题如果有上面是L下面就输入L,上面是R下面就输入R(因为LR必定是在上面连接出现的下面映射就好了),然后上面
D下面U,上面U下面跟D就能A掉了
参考代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
void solve(){
int n;
cin>>n;
string s;
cin>>s;
for(int i=0;i<s.size();i++){
if(s[i]=='L')cout<<'L';
else if(s[i]=='R')cout<<'R';
else if(s[i]=='D')cout<<'U';
else if(s[i]=='U')cout<<'D';
}
cout<<endl;
return ;
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
B. MEXor Mixup
思路
因为是最后所有数的XOR值等于b的值,那么我们假设前面0~a-1的数的XOR值等于x的,那么要使得 x XOR ? = b 那么 ?
可以用 x XOR b 来表示,因为 x XOR x XOR b =b,那么有以下三种情况:
1:x如果已经等于b了那么不用添加数了直接返回a就好了。
2:如果 ?即x XOR b 等于a那么原输入便应该是a+1与a所违背 那么我们插入x^b^1 和1 两个数那么 x^b^1^1^x同样等于b
所以最终值是a+2
3:如果 ?即x XOR b 不等于a那么添加一个数x^b即可,所以最终值是a+1
注意!!!:样例是5e4,a的范围是3e5如果暴力XOR在数据较强的情况下会TLE,听其他acmer说本次数据并不强,那么正确
应该如何写呢?通过xor找规律,令x等于a-1,当x==0时XOR值为0,接下去当x%4==1时XOR值为1,当x%4==2时XOR值为x+1,
当x%4==3时XOR值为0,当x%4==0时XOR值为x(通过找规律得出)
参考代码
#include<bits/stdc++.h>
using namespace std;
void solve(){
int a,b;
cin>>a>>b;
int x=a-1;
int xx;
if(x==0)xx=0;
else{
if(x%4==1)xx=1;
else if(x%4==2)xx=x+1;
else if(x%4==3)xx=0;
else if(x%4==0)xx=x;
}
int res=a;
if(xx==b){cout<<res<<endl;return;}
else if((xx^b)==a)res+=2;
else res+=1;
cout<<res<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
C. Carrying Conundrum
思路
思路就是将两个数拆开来,数一有 0~数一 共数一+1种可能,数二有 0~数二 共数二+1种可能.而数一的每种可能中
都可以参杂着数二的所有可能所以是(数一+1)*(数二+1),但因为ordered pairs of positive integers,所以有0的
情况需要排除即当上面为0或下面为0,例如12345,数一135,数二24.当上面为0下面为12345或者上面是12345,下面是0
都是非法的所以最后结果是(数一+1)*(数二+1)-2
参考代码
#include<bits/stdc++.h>
using namespace std;
void solve(){
string s;
cin>>s;
long long res1=0,res2=0;
for(int i=0;i<s.size();i++){
if(i%2==0){
res1=res1*10+(s[i]-'0');
}
else{
res2=res2*10+(s[i]-'0');
}
}
cout<<((long long)(res1+1)*(res2+1)-2)<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
D. Expression Evaluation Error
思路
见下代码中的注释
参考代码
#include<bits/stdc++.h>
using namespace std;
void solve(){
int a,b;
cin>>a>>b;
long long idx=1;//我这里开long long 是怕下面的a是1e9然后*10爆了(保险).
while(idx<a)idx*=10;
idx/=10;//7.8行操作负责找当前数的最大位数且开头为1后缀为0.
for(int i=0;i<b-1;i++){//一共b-1次操作加上最后的一次操作一共b个输出即切题
while(a-idx<b-1-i)idx/=10;//核心代码,例子111,从上得到idx为100,那么111-100<b-1-i的话idx就会退化一位说明前一
cout<<idx<<' ';//较大位不能保留了必须舍弃,假如b是12,那么去掉保留的a数这个操作1所以要减去1,i表示的是前面已经
a-=idx;//输出了多少个idx所以要减掉,当b=12,i=0,即第一次操作那么111-100==12-1-0所以说明100保留,因为后面的11全部
}//变成1那么就是100+11个1是12是满足b的但如果b=13的话100便要拆掉了,(非常棒的贪心写法)
cout<<a<<endl;//最后留下的a便是我们留下的最大的蛋糕,确保了Alice's sum is as large as possible.
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
我好菜~