“蔚来杯“2022牛客暑期多校训练营5

B-Watches

题意:

共有n个手表,每个手表的价钱为ai,老板有m元,若老板买其中k个手表,那么老板需要支付每个手表ai+i*k(i为原始列表的第i个)。求老板可以购买手表的最大数量。

题解:

根据题目条件可以想到二分答案,每次选取价钱最低的表。可以有两种写法:

第一种:

#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define endl '\n'
#define N  200005
#define fi first
#define se second
#define pb push_back
using namespace std;
const int inf=0x3f3f3f3f;
const double ex=1e-7;
const int mod=1e9+7;
int gcd(int a ,int b){ return b ? gcd(b,a%b) : a ;}
typedef pair<int,int>PII;
priority_queue<int,vector<int>,greater<int> > q;
int a[N],v[N],n,m;
int check(int x)
{
    int ans=0;
    for(int i=1;i<=n;i++) v[i]=a[i]+i*x;
    sort(v+1,v+1+n);
    for(int i=1;i<=x;i++)
    {
        ans+=v[i];
        if(ans>m) return 0;
    }
    return 1;
}
signed main()
{ios
    cin >>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin >>a[i];
    }
    int l=1,r=n;
    while(l<r)
    {
        int mid=(l+r+1)>>1;
        if(check(mid)) l=mid;
        else r=mid-1;
    }
    cout <<l<<endl;
    return 0;
}

 第二种:

#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define endl '\n'
#define N  500005
#define fi first
#define se second
#define pb push_back
using namespace std;
const int inf=0x3f3f3f3f;
const double ex=1e-7;
const int mod=1e9+7;
int gcd(int a ,int b){ return b ? gcd(b,a%b) : a ;}
typedef pair<int,int>PII;
priority_queue<int,vector<int>,greater<int> > q;
int a[N],b[N];
int n,m;
int check(int k)
{
    for(int i=1;i<=n;i++) b[i]=a[i]+i*k;
    sort(b+1,b+1+n);
    int ans=0;
    for(int i=1;i<=k;i++) ans+=b[i];
    return ans>=m;
}
signed main()
{ios
    cin  >>n>>m;
    for(int i=1;i<=n;i++) cin >>a[i];
    int l=1,r=n;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else  l=mid+1;
    }
    cout <<l-1<<endl;
    return 0;
}

C-Bit Transmission

题意:

有一个机器人以及一个长度为n的01串,机器人对于这个01串有3*n条陈述语句,每条语句给出该01串某个位置是否为1,不过这个机器人可能会说谎,已知其最多说谎一次,问能否确定该01串。

题解:

可以统计出对于每一位机器人给出1和0的次数。记录下每个位置0的次数和1的次数,显然两者同时大于等于二时,说谎了两次,不合题意,还有两者都等于0时,也不合题意;当其中一个为1,另一个大于等于2时说谎了一次。其中一个为一,另一个为0时,这时候要先看是否说谎,如果未说谎那么无法确定,如果说过谎,那么可以确定。

#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define endl '\n'
#define N  100005
#define fi first
#define se second
#define pb push_back
using namespace std;
const int inf=0x3f3f3f3f;
const double ex=1e-7;
const int mod=1e9+7;
int gcd(int a ,int b){ return b ? gcd(b,a%b) : a ;}
typedef pair<int,int>PII;
priority_queue<int,vector<int>,greater<int> > q;
int a[N][2],n,k;
string s;
int key[N];//记录答案
void solve()
{
    int cnt1=0;//记录是否存在01次数一个为1一个为0的情况。
    int cnt2=0;//记录说谎了几次
    for(int i=0;i<n;i++)
    {
       if((a[i][0]==0&&a[i][1]>0)||(a[i][0]>0&&a[i][1]==0)) 
       {
           //一方次数为0,另外一方次数为1时,如果未说谎那么无法确定,反之。
           //一方为0另外一方大于等于1时可以确定该位置
           if(a[i][0]>0) key[i]=0,cnt2|=a[i][0]==1;
           else key[i]=1,cnt2|=a[i][1]==1;
       }
       if((a[i][0]==1&&a[i][1]>=2)||(a[i][1]==1&&a[i][0]>=2))//次数为1的必定是说谎的
       {
           if(a[i][1]>=2) key[i]=1;
           else key[i]=0;
           cnt1++;
       }
       if((a[i][0]==a[i][1])||(a[i][0]>=2&&a[i][1]>=2)||cnt1>=2)
       {
           /*该数给出0和1的次数都为1或者都为0时不能确定,
           若两者都同时大于等于2说明说谎次数已经超过一次。
           在此之前说谎次数超过两次也不能确定
           */
           cout <<-1;return ;
       }
    }
    if(cnt2&&cnt1==0) //没有说谎一次且存在01次数一个为1一个为0的情况
    {
        cout <<-1;return ;
    }
    for(int i=0;i<n;i++) cout <<key[i];
}
signed main()
{ios
    cin >>n;
    for(int i=1;i<=3*n;i++)
    {
        cin >>k>>s;
        a[k][s=="YES"]++;//记录每个位置回答为0或1的次数
    }
    solve();
    return 0;
}

G-KFC Crazy Thursday

题意:

题解:

H-Cutting Papers

题意:

求x^2+y^2=n^2与 ∣x∣+∣y∣+∣x+y∣≤n的联合区域面积。

题解:

先取一个n值看看图像大概的样子,然后计算;显然S=πR^2+(R^2-πR^2/4)*2=(π/2+2)*R^2。又R=n/2;注意为浮点数计算。

#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define endl '\n'
#define N  200005
#define fi first
#define se second
#define pb push_back
using namespace std;
const int inf=0x3f3f3f3f;
const double ex=1e-7;
const int mod=1e9+7;
int gcd(int a ,int b){ return b ? gcd(b,a%b) : a ;}
typedef pair<int,int>PII;
priority_queue<int,vector<int>,greater<int> > q;
char s[1005][1005];
void solve()
{
    int n;
    cin >>n;
    printf("%.9lf",(0.5*acos(-1)+2)*(n/2.0)*(n/2.0));
}
signed main()
{ios
    int t = 1;
    //cin >>t;
    while(t--)
    {
        solve();
    }
    return 0;
}

K-Headphones

题意:

共有N对耳机,A拿出k对耳机,问B至少拿出多少副耳机可以保证B拿出的耳机对数大于k。每对耳机是不一样的。若有解则输出答案,无解输出-1。

题解:

由题可得拿出k对耳机后,还剩下N-k对耳机,即2*(N-k)副耳机,取最坏情况,B先拿出剩下每对耳机的一个,即N-k副。此时再拿x副就会有x对耳机,取x=k+1。所以B至少要拿出N-k+k+1,即N+1副耳机,只需要讨论剩下耳机是否小于等于N+1副即可。

#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define endl '\n'
#define N  200005
#define fi first
#define se second
#define pb push_back
using namespace std;
const int inf=0x3f3f3f3f;
const double ex=1e-7;
const int mod=1e9+7;
int gcd(int a ,int b){ return b ? gcd(b,a%b) : a ;}
typedef pair<int,int>PII;
priority_queue<int,vector<int>,greater<int> > q;
char s[1005][1005];
void solve()
{
    int n,k;
    cin >>n>>k;
    if(n+1>(n-k)*2)
    {
        cout <<-1<<endl;
    }else{
        cout <<n+1<<endl;
    }
}
signed main()
{ios
    int t = 1;
    //cin >>t;
    while(t--)
    {
        solve();
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值