AtCoder Beginner Contest 347
C - Ideal Holidays
这场做得最头疼的题
分析
容易想到先用(d_i+a+b-1)%(a+b)+1把d_i映射到\[1,a+b\]的区间再排序,但由于未知星期一是哪天,我们也无法确定映射后的d_i是星期几
关于这个映射可以自己推一下
我们取a+b=7看几个例子
对于
3 2 5
1 2 9
经映射后得
1 2 2
取第一天是星期一,所有di都在[1,2]内
而对于
4 2 5
1 2 7 9
经映射再排序后得
1 2 2 7
这时取第一天为星期一,d[4]为星期日,取第七天为星期一,第二天为星期三,我们发现此时不能使所有di都在[1,2]内
但若是b=4,a=3
4 3 4
1 2 7 9
经映射再排序后得
1 2 2 7
此时取第七天为星期一,第二天为星期三,我们发现此时能使所有di都在[1,3]内
而
4 3 4
1 2 6 9
显然又无法实现
所以能得到:映射再排序后存在d_i-d_{i-1}\>b就能够实现,但若是所有d_i原本就在[1,a]的范围内 呢,要处理这种情况,我们可以使d[n+1]=d[0]+a+b,或者做一个特判
代码
c++
void solve(){
int n,a,b,x;cin>>n>>a>>b;
vector<int>d;
rep(i,1,n){
cin>>x;
d.push_back((x+a+b-1)%(a+b)+1);//映射处理
}
sort(d.begin(),d.end());
d.push_back(d[0]+a+b);//相当于加上边界,处理一周七天时1 2 9的情况
rep(i,1,d.size()-1){
if(d[i]-d[i-1]>b){
cout<<"Yes";
return;
}
}
cout<<"No";
}
D - Popcount and XOR
贪心
分析
我们知道只有两数在二进制形式下当前位不同时,异或后的当前位才为1,反推过来,对于x \\oplus y=c ,c的二进制下当前位为1的话说明x或y的当前位一定是一1一0,而又由于要保证a与b个1都要刚好用尽,因此我们的贪心策略就是,对于c的二进制下为1的位,若a>b,则用a,此时x加上当前位的贡献,反之用b,y加上当前位的贡献,这样以后再判断是否满足ab相等且大于等于0
代码
c++
void solve(){
int a,b,x=0,y=0,c;cin>>a>>b>>c;
rep(i,0,60){
if(c>>i&1){
if(a>b){
x+=(1ll<<i);//赛时甚至是用的快速幂(っ °Д °;)っ
a--;
}
else{
y+=(1ll<<i);
b--;
}
}
}
if(a!=b||a<0||b<0){
cout<<"-1";
return;
}
rep(i,0,60){
if(!(c>>i&1)&&a){
x+=(1ll<<i);
y+=(1ll<<i);
a--;
}
}
if(a){//还要特判a或者b是否有剩
cout<<"-1";
return;
}
cout<<x<<" "<<y;
}