Educational Codeforces Round 138 (Rated for Div. 2)-C. Number Game

我的思路可能有点复杂,,,,
调试了很久orz

#include <bits/stdc++.h>
using namespace std;
int a[105];
int n,m,ans;
int main(){
	int T;cin>>T;
	while(T--){
		cin>>n;
		int cn=0;
        ans=0;
		for(int i=1;i<=n;i++) cin>>a[i];
		sort(a+1,a+n+1);


        if(a[1]>1){//情况一:一个1也没有,只能输出0
            printf("0\n");
            continue;
        }
        if(a[1]==1&&a[2]>1){
            printf("1\n");//情况二:只有一个1,选手A只能选择1
            continue;
        }
		for(int i=1;i<=n;i++){
			if(a[i]==1) cn++;//统计1的个数
			else break;
		}
        //实际上B每操作一次,就相当于删除了一个数(A一定不能再选这个数了)
        //A优先操作最大的,B优先操作最小的
        //那B优先操作1的个数,因为A最后一个操作的数一定是1,所以看在k回合内B能否把1删除完
        //于是先统计1的个数cn,最多的回合数一定是cn

        int id=1,cnt=0;//统计A以最后一个1为起点,可以操作的数的个数
        //A操作时最坏的情况:1,2,3,4……
        //当然a数组可以是这样:1,2,2,2……
        for(int i=cn;i<=n;i++){
            if(a[i]>id){
                break;
            }
            id++;cnt++;
        }
        if(cnt>=cn) {//情况三:此时最多只能进行cn回合(cn是1的个数)
            printf("%d\n",cn);
            continue;
        }

        //情况四:在情况三不成立的情况下,此时进行回合数一定小于cn
        //此时保证一定能进行(cn+1)/2回合
        //更优:我们可以把选手A的起点前移动,使得进行的回合数尽可能的多

        //样例:
        //1 1 1 1 <前面是B操作的,后面是A操作的> 1 3 4 5    //此时A操作的第二个数->3就不满足了
        //但是我们可以把A的起点往前移动,于是这样
        //1 1 1 <前面是B操作的,后面是A操作的> 1 1 3 4 5    //这样的话回合数可以是4
        int f;
        ans=(cn+1)/2;
		for(int i=cn;i<=n;i++){//先默认AB操作的总长度为1的个数cn
            f=1;
            for(int j=(i/2+1);j<=i;j++){//(i/2)+1是A操作的第一个数
                if(a[j]>(j-(i/2))) {f=0;break;}//(j-(i/2))从1开始:1,2,3……
            }
            if(f==1) ans=(i+1)/2;
            else break;
		}
		printf("%d\n",ans);
	} 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值