Codeforces Round #750 (Div. 2) A B C D F1
A. Luntik and Concerts
思路:因为题目保证了a,b,c的数量至少为1,那么易得a,b,c可以任意组成0~a + b * 2 + c * 3 中的任意一个数字,那么为了使两个舞台的相差时间最短,那么显然判断a + b * 2 + c * 3 的奇偶性即可。
参考代码:
# include <bits/stdc++.h>
using namespace std;
# define snow ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ; cout. tie ( 0 ) ;
using ll= long long ;
int main ( ) {
snow;
int t;
cin>> t;
while ( t-- ) {
int a, b, c;
cin>> a>> b>> c;
ll ans= a+ b* 2 + c* 3 ;
if ( ans% 2 == 0 ) cout<< 0 << endl;
else cout<< 1 << endl;
}
return 0 ;
}
B. Luntik and Subsequences
思路:B题其实模拟一下就很容易找到规律,因为要使他的子序列构成 nearly full,所以我们只要关注子序列中的0和1的数量即可。会容易发现最后的方案数是1的个数乘以2的出现数的次方即可,需要注意方案数最大是2^60次方需要开long long。
参考代码
# include <bits/stdc++.h>
using namespace std;
# define snow ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ; cout. tie ( 0 ) ;
using ll= long long ;
const int N= 65 ;
int a[ N] ;
int main ( ) {
snow;
int t;
cin>> t;
while ( t-- ) {
int n;
cin>> n;
int res1= 0 , res0= 0 ;
for ( int i= 0 ; i< n; i++ ) {
cin>> a[ i] ;
if ( a[ i] == 1 ) res1++ ;
else if ( a[ i] == 0 ) res0++ ;
}
ll ans= res1* pow ( 2 , res0) ;
cout<< ans<< endl;
}
return 0 ;
}
C. Grandma Capa Knits a Scarf
思路:双指针扫描,最大时间复杂度是26*N,时间复杂度足够。
参考代码:
# include <bits/stdc++.h>
using namespace std;
# define snow ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ; cout. tie ( 0 ) ;
using ll= long long ;
const int N= 65 ;
int a[ N] ;
int main ( ) {
snow;
int t;
cin>> t;
while ( t-- ) {
int n;
cin>> n;
string s;
cin>> s;
int ans= n+ 1 ;
for ( char i= 'a' ; i<= 'z' ; i++ ) {
int l= 0 , r= s. size ( ) - 1 ;
int cz= 0 ;
while ( l<= r) {
if ( s[ l] == s[ r] ) {
l++ , r-- ;
}
else if ( s[ l] == i) {
l++ ;
cz++ ;
}
else if ( s[ r] == i) {
r-- ;
cz++ ;
}
else {
cz= n+ 1 ;
break ;
}
}
ans= min ( ans, cz) ;
}
if ( ans== n+ 1 ) cout<< - 1 << endl;
else cout<< ans<< endl;
}
return 0 ;
}
D. Vupsen, Pupsen and 0
思路:题目要求的是构造一个b数组,使得a[1]*b[1] + a[2]*b[2]… a[n]*b[n]=0,并且所有的 ∣ b [ 1 ] ∣ \left\vert b[1]\right\vert ∣ b [ 1 ] ∣ +… ∣ b [ n ] ∣ \left\vert b[n]\right\vert ∣ b [ n ] ∣ 值要小于等于 1 0 9 10^9 1 0 9 ,显然偶数情况下我们只需要进行配对可以分成n/2个组合,例如a[1]和a[2]相对应的b[1]=a[2],b[2]=-a[1] 那么必定能使得最后的和的值为0。如果n是奇数的话,我们只需要将前面三个数进行处理例如 a[1] 和 a[2] 和 a[3] 相对应的 b[1]=a[3],b[2]=a[3] ,b[3]=-(a[1]+a[2]) 并且后面部分按照偶数情况处理那么便可以了,但是需要注意前面选择的三个数字可能会出现 a b c 但a = -b 的情况那么-(a+b)会变成0,显然与题目要求的b数组中不能出现0相悖,再仔细思考会发现我们只需要进行分类讨论前三个数即可,如果a=-b那么c的出现必然会使得三个数中至少其中两个数是正数或是负数,那么我们只需要让那两个正数或者负数为上面情况中的a和b那么-(a+b)必然不会是0,因此这个坑我们也可以巧妙处理了。
参考代码
# include <bits/stdc++.h>
using namespace std;
const int N= 1e5 + 10 ;
int a[ N] ;
# define snow ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ; cout. tie ( 0 ) ;
int main ( ) {
snow;
int t;
cin>> t;
while ( t-- ) {
int n;
cin>> n;
if ( n% 2 == 0 ) {
int g= n/ 2 ;
while ( g-- ) {
int a, b;
cin>> a>> b;
cout<< - b<< ' ' << a<< ' ' ;
}
cout<< endl;
}
else if ( n% 2 == 1 ) {
int a, b, c;
cin>> a>> b>> c;
if ( a== - b) {
if ( b== c) {
cout<< - ( b+ c) << ' ' << a<< ' ' << a<< ' ' ;
}
else if ( a== c) {
cout<< b<< ' ' << - ( a+ c) << ' ' << b<< ' ' ;
}
else {
cout<< - ( b+ c) << ' ' << a<< ' ' << a<< ' ' ;
}
}
else {
cout<< c<< ' ' << c<< ' ' << - ( a+ b) << endl;
}
n-= 3 ;
int g= n/ 2 ;
while ( g-- ) {
cin>> a>> b;
cout<< - b<< ' ' << a<< ' ' ;
}
cout<< endl;
}
}
return 0 ;
}
F1.Korney Korneevich and XOR (easy version)
思路:题目要求的是从A序列中选取一段上升序列(一开始读假题了),那么限制了可异或的条件,也就是132的话不能选取1 ^ 3 ^ 2的的值。本题n最大是1e5+10,a的值最大是500,熟悉了的话很快就能发现这是一个dp背包问题,并且由于5e7的复杂度尚可接受,本题可直接采取暴力dp背包求解。
参考代码+详细注释:
# include <bits/stdc++.h>
using namespace std;
const int N= 1e5 + 10 ;
int a[ N] ;
int f[ N] ;
# define snow ios:: sync_with_stdio ( false) ; cin. tie ( 0 ) ; cout. tie ( 0 ) ;
int main ( ) {
snow;
int n;
cin>> n;
for ( int i= 1 ; i<= n; i++ ) cin>> a[ i] ;
memset ( f, 0x3f , sizeof f) ;
f[ 0 ] = 0 ;
for ( int i= 1 ; i<= n; i++ ) {
for ( int j= 0 ; j< 512 ; j++ ) {
if ( f[ j] < a[ i] ) f[ j^ a[ i] ] = min ( f[ j^ a[ i] ] , a[ i] ) ;
}
}
int res= 0 ;
for ( int i= 0 ; i< 512 ; i++ ) {
if ( f[ i] < 512 ) res++ ;
}
cout<< res<< endl;
for ( int i= 0 ; i< 512 ; i++ ) if ( f[ i] < 512 ) cout<< i<< ' ' ;
cout<< endl;
return 0 ;
}