题意:
共有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;
}
题意:
有一个机器人以及一个长度为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;
}
题意:
题解:
题意:
求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;注意为浮点数计算。
![](https://img-blog.csdnimg.cn/efb60cc1d4f94a97bf2e8bf5d090637e.png)
#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;
}
题意:
共有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;
}