Codeforces Round #671 (Div. 2) A-D2

Codeforces Round #671 (Div. 2)

A. Digit Game

问题分析:

n个数字,R只能删除任意奇数位的数字,B只能删除任意偶数位的数字
B先走,然后如果最后剩的 数字是奇数R赢了,否则B赢了

当n为奇数的时候 ,奇数位的数量是n/2+1; R先走,最后一定会剩下一个奇数位的数字
这时候只要 所有奇数位里 有一个 奇数就一定是 R赢得比赛
当n为偶数的时候,奇/偶位置都是n/2 而且R先走,最后一定会剩下一个 偶数位的数字
同理,偶数位有偶数 就一定是B赢

AC代码:


 #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define mem(a,b) memset((a),(b),sizeof(a));
#define lowbit(a) ((a)&-(a))
const ll inf=0x3f3f3f3f;//1061109567,2*未超int,allinf=mem(a,0x3f,sizeof(a));
const int N=2e5+10;
ll a[32];
ll sum;
int main(){
       // #define io
#ifdef io
        freopen("in.txt","r",stdin);
#endif
        cin.tie(0);
        int t;
        cin>>t;
        while(t--){
                int n;
                cin>>n;
                int ro,bd;
                ro=bd=0;
                string s;
                cin>>s;
                        for(int k=0;k<s.length();k++){
                                int x=s[k]-'0';
                                int i=k+1;
                              //  cout<
                        if(i%2){
                                if(x%2)
                                ro++;
                        }else{
                                if(!(x%2)) bd++;
                        }
                }
                if(n%2){
                        if(ro!=0)
                        cout<<1<<endl;
                        else cout<<2<<endl;
                }else {
                        if(bd!=0)
                        cout<<2<<endl;
                        else cout<<1<<endl;
        }
        }
        return 0;
}

B. Stairs

问题分析:

看图吧
阶梯 数量 变化是 1 3 7 15
为 n2+1 每次增加 比前面阶数+1个
而组成阶梯的 小方块数量每列 是 等差数列
即 sum= n
(n+1)/2;
然后 问的是不同阶数的最大总数 枚举暴力

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define mem(a,b) memset((a),(b),sizeof(a));
#define lowbit(a) ((a)&-(a))
const ll inf=0x3f3f3f3f;//1061109567,2*未超int,allinf=mem(a,0x3f,sizeof(a));
const int N=2e5+10;
ll a[32];
ll sum;
int main(){
       // #define io
#ifdef io 
        freopen("in.txt","r",stdin);
#endif
        cin.tie(0);
        int t;
        while(cin>>t){
                while(t--){                                                              
                ll x;
                cin>>x;
                ll cnt=0;
                ll temp;
                for(ll i=1;;){
                        temp=(i+1)*i/2;
                        if(x<temp)break;
                        x-=temp;
                        cnt++;
                        i=i*2+1;
                }
                cout<<cnt<<endl;      
                }
        }
        return 0;
}

C. Killjoy

问题分析:

。。。。好难,。,。
一个人可以在赛前或者赛后感染其他和他 分数相同的人
然后通过每场比赛 感染着可以操作所有人分数,但是所有分数变化之差必须为0
问 最少需要 几次竞赛 才能感染所有的人

分为几种情况

  1. 所有的人的分数 都和他相同 直接赛前( 0)
  2. 所有人中至少有一个人的分数和他相同 赛前感染,赛中所有 分数变化产生的差值全都转移到 赛前被感染的人身上(1)
  3. 所有的的分制之和的平均值等于 初始感染者的分数,赛中 加加减减 所有人变为,。,。(1)
  4. 不满足以上任何一种情况
    先在第一场 赛中 操作 一个人的分数变为 初始感染者相同,赛后感染,,,,
    第二场 赛中 秀和第二种情况的操作,,,然后赛后所有人感染(2)

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define mem(a,b) memset((a),(b),sizeof(a));
#define lowbit(a) ((a)&-(a))
const ll inf=0x3f3f3f3f;//1061109567,2*未超int,allinf=mem(a,0x3f,sizeof(a));
const int N=2e5+10;
ll a[32];
ll sum;
int main(){
       // #define io
#ifdef io 
        freopen("in.txt","r",stdin);
#endif
        cin.tie(0);
        int t;
        cin>>t;
        while(t--){
                int n,m;
                cin>>n>>m;
                int sum=0;
                int flag=0;
                for(int i=0;i<n;i++){
                        int x;
                        cin>>x;
                        sum+=x;
                        if(x==m)flag++;
                }
                if(flag==n)cout<<0;
                else if(flag||sum==n*m)cout<<1;
                else cout<<2;
                cout<<endl;
        }
        return 0;
}

D1. Sage’s Birthday (easy version)

问题分析:

给定一个 每一项各不相同的数组
要求重新排列 使得 某项比理他最近的 左右两侧的数最小这样的项数的数量最多

怎么说呢 一想就是 大数夹小数
极端的想法就是取两端

分两种情况

  1. 奇数 可以夹的数的数量是 n/2
    大数从 n/2+1开始 取 小数从1开始 因为 大数 小数不相等要注意 最后一项
  2. 偶数 夹的数量是 n/2-1
    大数从n/2+1开始 小数从1 直接一组 一组输出记性
    具体看代码

AC代码:


 #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define mem(a,b) memset((a),(b),sizeof(a));
#define lowbit(a) ((a)&-(a))
const ll inf=0x3f3f3f3f;//1061109567,2*未超int,allinf=mem(a,0x3f,sizeof(a));
const int N=2e5+10;
int a[N];
int main(){
       // #define io
#ifdef io
        freopen("in.txt","r",stdin);
#endif
        cin.tie(0);
                int n;
                cin>>n;
                for(int i=1;i<=n;i++){
                        cin>>a[i];
                }
                sort(a+1,a+n+1);
                if(n%2){
                        cout<<n/2<<endl;
                        for(int i=n/2+1;i<n;i++){
                                cout<<a[i]<<" "<<a[i-n/2]<<" ";
                        }
                        cout<<a[n]<<endl;
                }else{
                        cout<<n/2-1<<endl;
                        for(int i=n/2+1;i<=n;i++){
                                cout<<a[i]<<" "<<a[i-n/2]<<" ";
                        }
                        cout<<endl;
                }
        return 0;
}

D2. Sage’s Birthday (hard version)

问题分析:

和D1题意基本相同 不同的是 各项允许有相同的 数字出现
想了下 还是D1的做法。。。因为 D1呢种 排序方案感觉在D2中也是最优的
为什么这么说呢
因为 排完序后 是从中间部分 往后作为大数 ,而从头往后作为小数
这样就尽量保证较小的大数一定夹的是较小的小数
例子 举一个 特殊的吧

9
444444555

答案:5夹4
`
2
444454545

| - | - | - | - |
`
然后就是统计数量不在是简单的公式了 这个就需要判断
这个简单了 扫一遍嘛

AC代码:


 #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define mem(a,b) memset((a),(b),sizeof(a));
#define lowbit(a) ((a)&-(a))
const ll inf=0x3f3f3f3f;//1061109567,2*未超int,allinf=mem(a,0x3f,sizeof(a));
const int N=2e5+10;
int a[N],b[N];
int main(){
       // #define io
#ifdef io
        freopen("in.txt","r",stdin);
#endif
        cin.tie(0);
                int n;
                cin>>n;
                for(int i=1;i<=n;i++){
                        cin>>a[i];
                }
                sort(a+1,a+n+1);
                int ans=0;

                if(n%2){
                        for(int i=n/2+1;i<n;i++){
                                b[ans++]=a[i];
                                b[ans++]=a[i-n/2];
                        }
                        b[ans++]=a[n];
                }else{
                        for(int i=n/2+1;i<=n;i++){
                                b[ans++]=a[i];
                                b[ans++]=a[i-n/2];
                        }
                }
                int sum=0;
                for(int i=1;i<ans;i+=2){
                        if(b[i]<b[i-1]&&b[i]<b[i+1])sum++;
                }
                cout<<sum<<endl;
                for(int i=0;i<ans;i++){
                        cout<<b[i]<<" ";
                }
                cout<<endl;
        return 0;
}

你可能感兴趣的:(CodeForces)