Codeforces Round 867 (Div. 3)(A-E)
A. TubeTube Feed
签到题
思路
往后走,每次减一,记录当前所能得到最大的bi
完整代码
#include<bits/stdc++.h>
using namespace std ;
#define ll long long
inline ll read(){
ll s=0 ; char g=getchar() ; while( g>'9'||g<'0')g=getchar() ;
while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ;
}
ll a[51] , b[51] ;
void solve(){
ll n = read() , k = read() ;
for( int i = 1 ; i <= n ; ++i )a[i] = read() ;
for( int i = 1 ; i <= n ; ++i )b[i] = read() ;
ll ans = -1 , mans = 0 ;
for( int i = 1 ; i <= n ; ++i ){
if( k >= a[i] && b[i] > mans )mans = b[i] , ans = i ;
k-- ;
}
cout<<ans<<endl ;
}
int main(){
ll q = read() ;
while( q-- ){
solve() ;
}
return 0 ;
}
B. Karina and Array
ssw:笑死,搞忘初值不能为0了
思路
通常来说,记录数列中的最大值和次大值,相乘即答案
但存在负值,所以还要记录最小值和次小值
二者取max
注意下初始值的问题,不要赋值为0
完整代码
#include<bits/stdc++.h>
using namespace std ;
#define ll long long
void solve(){
ll n ; cin>> n ;
ll max1 = -1000000001 , max2 = -1000000001 , min1 = 1000000001 , min2 = 1000000001 ;
for( int i = 1 ; i <= n ; ++i ){
ll x ; cin>>x ;
if( x >= max1 ){
max2 = max1 ; max1 = x ;
}
else if( x >= max2 )max2 = x ;
if( x <= min1 ){
min2 = min1 ; min1 = x ;
}
else if( x <= min2 )min2 = x ;
}
cout<<max( max1*max2 , min1*min2 )<<endl ;
}
int main(){
ll q ; cin>>q ;
while( q-- ){
solve() ;
}
return 0 ;
}
C. Bun Lover
XXX:这不都是一眼题吗?
思路
主要思路
找规律嘛, f[n+1] = f[n]+2*n+1
然后拆开递推式即可f[n]=2+2n+n^2
代码
void solve(){
ll n ; cin>> n ;
cout<<2ll+2ll*n+n*n<<endl ;
}
D. Super-Permutation
fxs:看6就行
橘子熊:我猜的,但对了
思路
主要思路
首先明确我们是要利用前缀和取模后再凑出一组 0 到 n-1
然后看看样例取模,就能找到规律 0 5 1 4 2 3
反向推出数列即可
代码
void solve(){
int n ; cin>>n ;
if( n == 1 )cout<<1<<endl ;
else if ( n%2 )cout<<-1<<endl ;
else {
for( int i = 0 ; i < n ; ++i){
if( i%2 )cout<<n-i<<" " ;
else if( i==0 )cout<<n<<" " ;
else cout<<i<<" " ;
}
cout<<endl ;
}
}
E. Super-Permutation
fxs:气死了
ssw:睡觉
思路
主要思路
奇数不合法,只考虑n为偶数的情况
首先考虑到,若一个字母的总数大于 n/2 , 那么必定不合法
然后我们考虑到,一次交换操作,最多使2组对应的不同字母被破坏
然后两两相消就行
最后只剩下一种字母对 或者 刚好消完
对于剩下的一种字母对,操作次数再加上剩余对数就行
代码
#include<bits/stdc++.h>
using namespace std ;
#define ll long long
char g[200005] ;
int c[27] , d[27] , tot = 0 , ans = 0 ;
void solve(){
int n ; cin>>n ; memset( c , 0 , sizeof(c) ); memset( d , 0 , sizeof(d) ) ; tot = 0 , ans = 0 ;
int maxx = 0 ;
for( int i =1 ; i <= n ; ++i ){
cin>>g[i];
int cha = g[i]-'a' ;
d[cha]++ ; maxx = max( maxx , d[cha] ) ;
}
if( n%2 ){cout<<"-1"<<endl ;return;}
for( int i =1 ; i <= n/2 ; ++i ){
int cha = g[i]-'a' ;
if( g[i] == g[n-i+1] ){
c[cha]++ , tot++ ;
}
}
if( maxx > n/2 ){cout<<-1<<endl ; return ;}
priority_queue<int>q ;
for( int i = 0 ; i < 26 ; ++i )
if( c[i] != 0 )q.push(c[i]) ;
int las = 0 ;
int x = 0 ; ans = 0 ;
if(!q.empty())x = q.top() ;
while( !q.empty() ){
x = q.top() ; q.pop() ; int y = 0 ;
if( !q.empty() ){ y = q.top(); q.pop(); }
if(y==0)las = x ;
else{
x -= y ; ans += y ; if(x!=0) q.push( x ) ;
}
}
ans += las ;
cout<<ans<<endl ;
}
int main(){
int q ; cin>>q ;
while( q-- )solve() ;
return 0 ;
}
注:被hack了 比如aabbbccccbbbaa
,是因为出现了 3 3 2 , 本来可以全消除, 但却留下了2
改了下,发现没必要这么消除,只需要记录最大的c[i]是否过半即可
int ans = 0 ; maxx = 0 ;
for( int i = 0 ; i < 26 ; ++i )ans += c[i] , maxx = max( maxx , c[i] ) ;
if( maxx > ans/2 )cout<<maxx<<endl ;
else if( ans == 0 )cout<<0<<endl ;
else cout<<(ans-1)/2+1<<endl ;