文章目录
题目链接:https://codeforces.com/contest/1991
写在前面
昨晚打的这场cf状态特别不好,打了不到半小时就开始发困了,边听歌边打都止不住困意,打的是一言难尽,下次打cf之前先睡个半小时,身体真是吃不消······
A-Maximize the Last Element
思路
签到题,通过观察不难发现:在数列中是奇数次则可以被取到,是偶数次则无法被取到
遍历一遍找奇数次最大值即可
void solve(){
int n;cin >> n;
int maxn=0,k=0;
for(int i=1;i<=n;++i){
cin >> a[i];
if(i & 1) maxn=max(maxn,a[i]);
}
cout << maxn << endl;
return ;
}
B- AND Reconstruction
思路
考点:构造+模拟
由于
b
i
=
a
i
A
N
D
a
i
+
1
b_i = a_i AND a_{i+1}
bi=aiANDai+1 ,显然我们可以想到OR运算(或运算)
构造
a
i
=
b
i
O
R
b
i
+
1
a_i=b_i OR b_{i+1}
ai=biORbi+1,上述构造可以满足
b
2
到
b
n
−
2
b_2到b_{n-2}
b2到bn−2,这时我们令
a
1
=
b
1
,
a
n
=
n
n
−
1
a_1=b_1,a_n=n_{n-1}
a1=b1,an=nn−1即可
最后检验是否合法就行
编程
void solve(){
int n;cin >> n;
for(int i=1;i<n;++i) cin >> b[i];
a[1]=b[1],a[n]=b[n-1];
int flag=0;
for(int i=2;i<n;++i) a[i]=(b[i]|b[i-1]);
for(int i=1;i<n;++i){
if((a[i] & a[i+1])!=b[i]){
flag=1;
break;
}
}
if(flag) cout << -1 << endl;
else{
for(int i=1;i<=n;++i) cout << a[i] << " ";
cout << endl;
}
return ;
}
C- Absolute Zero
思路1
考点:构造+模拟
赛时思路: 每次都找数列中的最大值,并取
m
i
d
=
最大值
/
2
mid=最大值/2
mid=最大值/2进行操作,每次可保证值域缩小一半,可以保证在40次以内是可行的
编程1
void solve(){
int n;cin >> n;
priority_queue<int> q;
for(int i=1;i<=n;++i){
int x;cin >> x;
q.push(x);
}
vector<int> ans;
int flag=0;
for(int i=1;i<=40;++i){
if(q.top()==0){
flag=1;
break;
}
int mid=(q.top()+1) >> 1;
ans.push_back(mid);
queue<int> t;
while(!q.empty()) t.push(abs(q.top()-mid)),q.pop();
while(!t.empty()) q.push(t.front()),t.pop();
}
if(flag==0){
cout << -1 << endl;
return ;
}
cout << ans.size() << endl;
for(auto i : ans) cout << i << " ";
cout << endl;
return ;
}
思路2
首先我们知道
2
30
=
1073741824
>
1
e
9
2^{30}=1073741824>1e9
230=1073741824>1e9,那么我们可以用二进制来解决这道题
先考虑无解的情况,当一个数列有奇数有偶数时,它就无法等于0
因此,这个数列必须是纯奇数 or 纯偶数才有解
在有解的情况下,我们从最大值的一半开始操作,即从
2
29
2
28
⋅
⋅
⋅
⋅
⋅
⋅
2
0
2^{29} 2^{28}······2^0
229228⋅⋅⋅⋅⋅⋅20从上往下进行操作
这时如果是奇数的数列,在最后减去1时全部会变为0
如果为偶数的数列,在
2
1
2^1
21已经变为0了,在操作一次
2
0
2^0
20会多出一个1,最后需要在末尾添上1的操作
编程2
void solve(){
int n;cin >> n;
int flag1=0,flag2=0;
for(int i=1;i<=n;++i){
cin >> a[i];
if(a[i] & 1) flag1=1;
else flag2=1;
}
if(flag1 && flag2){
cout << -1 << endl;
return ;
}
vector<int> ans;
for(int i=29;i>=0;i--){
ans.push_back(1 << i);
}
if(flag2) ans.push_back(1);
cout << ans.size() << endl;
for(auto i : ans) cout << i << " ";
cout << endl;
return ;
}
D- Prime XOR Coloring
思路
考点:构造
众所周知有四色定理:即任何一张地图只用四种颜色就能使具有共同边界的国家着上不同的颜色(我是蒟蒻不会)
因此在本题中大于等于6的数可以大胆猜测颜色至多为4种
一个朴素的想法是奇数同种颜色,偶数同种颜色,这样可以让同色的异或结果为偶数,但是质数2推翻了这个想法
因此我们可以考虑按4的同余类染色,这样就可以使得同色的异或结果为4的倍数,必定不是质数
编程
void solve(){
int n;cin >> n;
if(n==1){
cout << 1 << endl;
cout << 1 << endl;
}
else if(n==2){
cout << 2 << endl;
cout << 1 << " " << 2 << endl;
}
else if(n==3){
cout << 2 << endl;
printf("1 2 2\n");
}
else if(n==4){
cout << 3 << endl;
printf("1 2 2 3\n");
}
else if(n==5){
cout << 3 << endl;
printf("1 2 2 3 3\n");
}
else{
cout << 4 << endl;
for(int i=1;i<=n;++i){
cout << ((i%4==0)? 4 : i%4) << " ";
}
cout << endl;
}
return ;
}