cf1270

A. Card Game

模拟题,直接上代码

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
int main(){
    int t,n,k1,k2;
    int a[105],b[105];
    cin>>t;
    while(t--){
        cin>>n>>k1>>k2;
        int max1=0,max2=0;
        for(int i=1;i<=k1;i++){
            cin>>a[i];
            if(a[i]>max1)max1=a[i];
        }
        for(int i=1;i<=k2;i++){
            cin>>b[i];
            if(b[i]>max2)max2=b[i];
        }
        if(max1>max2)cout<<"YES"<<endl;
        else{
            cout<<"NO"<<endl;
        }
    }
    return 0;
}

B. Interesting Subarray

题目大意是给一个数列,要求在这个数列中找到一个子序列,使得序列中的最大值与最小值的差大于等于子序列的数的个数。

刚开始的思路是找最大值,然后从最大值往左右两边搜。然后发现这么做没有必要,只要存在每两个数的差大于等于2,就一定存在这样的子序列。那么只要在输入的时候判断一下就可以了。

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=2e5+5;
int t,n,a[maxn];

int main(){
    cin>>t;
    int flag=0;
    while(t--){
       cin>>n;
       for(int i=1;i<=n;i++){
           cin>>a[i];
           if(i!=1){
               if(abs(a[i]-a[i-1])>=2&&!flag){
                   cout<<"YES"<<i-1<<" "<<i<<endl;
                   flag=1;
               }
           }
       }
       if(!flag)cout<<"NO"<<endl;
    }
    return 0;
}

C. Make Good

题目大意是给定一个数列a,加上0个或1个或2个或3个的数,使得添完数之后的序列满足数之和等于两倍的所有数的异或。即满足a1+a2+a3+…+an=2*(a1⊕a2⊕a3…⊕an)。

思路:将上面等式的左边用sum表示,右边用XOR表示,那么式子就变成了sum=2*XOR。根据异或的性质,a⊕a=0,a⊕0=a,那么在上述 数列中增加一个XOR,上述等式就变成了sum+XOR=2 * (XOR⊕XOR),即sum+XOR=0;变成这样的式子之后,就简单了许多。只要在加上一个sum+XOR,就满足了题目的要求。即(sum+XOR)+(sum+XOR)=(sum+XOR)⊕0;

#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ll long long 
using namespace std;
//a^a=0,a^b^b=a^0=a;
const int maxn=1e5+5;
ll n,a[maxn];
int main(){
    ll t;
    cin>>t;
    while(t--){
        memset(a,0,sizeof(a));
        cin>>n;
        ll sum=0,xor1=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            sum+=a[i];
            xor1^=a[i];
        }
    cout<<2<<endl;
    cout<<xor1<<" "<<sum+xor1<<endl;
    }
    return 0;
}

D. Strange Device

题目大意,给定一个数列,数列中的每一个数都不一样。现在有一个机器,这个机器能够查询前k个数,并且返回的是第m大的数。但是现在只知道k,不知道m,要求你查询不多于n次,确定m的值。

这个题目看完感觉都没怎么看懂,然后看了题解,才明白是啥意思。要求出m,我们需要查询k+1次。对于前k+1个数,每次删去一个x,然后查询剩余的k个数。那么根据删去的数的情况,可以得到两种结果。

1)x<=第m大的数,得到的是第m+1大的数,并且出现的是m次;

2)x>第m大的数,得到的是第m大的数,出现的是k+1-m次。

那么我们只需要记录第m+1大的数出现的次数,就能得到m。

#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
#define ll long long

const int INF=0x3f3f3f3f;

const int N=50;

map<int,int>mp;

int n,k;

void print(int x){//查询的数的位置
    cout<<"?";
    for(int i=1;i<x;i++)cout<<" "<<i;
    for(int i=x+1;i<=k+1;i++)cout<<" "<<i;
    cout<<"\n";
    fflush(stdout);
}

int main(){
    cin>>n>>k;
    for(int i=1;i<=k+1;i++){
        print(i);
        int pos,val;
        cin>>pos>>val;//返回的第m大的数的位置和值
        mp[val]++;
    }
    cout<<"! "<<mp.rbegin()->second;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值