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 ; 
posted @ 2023-04-25 16:04  蓝银杏-SSW  阅读(52)  评论(0编辑  收藏  举报
//结束