B题 Watches
分析
第一行给定n,m,分别表示n块手表和拥有的钱,第二行,给定n个数a[i],表示每块手表的价格。另外,每块手表会额外花费 i*k的价格,k表示一共买了几块。
代码如下
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=200010;
const int mod=1e9+7;
int a[N],b[N];
int sum[N];
int n,m;
bool check(int x)
{
for(int i=1;i<=n;i++) b[i]=a[i]+x*i;
// for(int i=1;i<=n;i++) cout<<b[i]<<" ";
// cout<<endl;
sort(b+1,b+n+1);
int res=0;
for(int i=1;i<=x;i++) res+=b[i];
if(res<=m) return true;
return false;
}
signed main()
{
while(cin>>n>>m)
{
for(int i=1;i<=n;i++) cin>>a[i];
int l=0,r=n;
int ans;
while(l<=r)
{
int mid=l+r>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
//cout<<l<<" "<<r<<endl;
}
cout<<ans<<endl;
}
}
C题 Bit Transmission
分析
这里是引用按照题意模拟,看有没有没访问到的地方、YES或NO个数都大于1、YES或NO个数相同、出现大于1个YES和NO都出现过的位置、假如没有YES和NO都出现过的位置,但有某个位置YES和NO只出现了一次,因为错误的地方至多出现一个,无法判断这里是1还是0----以上均输出-1,否则输出ans。
代码如下
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int maxn=100010;
int a[maxn][2];
int b[maxn];
int n;
string s;
int main(){
while(scanf("%d",&n)!=EOF){
int x;
fill(a[0],a[0]+maxn*2,0);
for(int i=1;i<=3*n;i++){
scanf("%d",&x);
cin>>s;
if(s[0]=='Y'&&s[1]=='E'&&s[2]=='S') a[x][1]++;
else a[x][0]++;
}
bool flag=true;
int ans=0;
int ans2=0;
for(int i=0;i<n;i++){
if(a[i][0]==a[i][1]&&a[i][1]==0){
flag=false;
break;
}
if(a[i][0]==a[i][1]&&a[i][1]==1){
flag=false;
break;
}
if(a[i][0]>=2&&a[i][1]==0){
b[i]=0;
}
else if(a[i][1]>=2&&a[i][0]==0){
b[i]=1;
}
else if(a[i][0]>=2&&a[i][1]==1){
b[i]=0;
ans++;
}
else if(a[i][1]>=2&&a[i][0]==1){
b[i]=1;
ans++;
}
else if(a[i][1]==1&&a[i][0]==0||a[i][1]==0&&a[i][0]==1){
ans2++;
continue;
}
}
if(ans==0&&ans2>=2) flag=0;
if(ans==0&&ans2==1){
for(int i=0;i<n;i++){
if(a[i][1]==1&&a[i][0]==0){
b[i]=0;
break;
}
else if(a[i][1]==0&&a[i][0]==1){
b[i]=1;
break;
}
}
}
if(ans==1){
for(int i=0;i<n;i++){
if(a[i][1]==1&&a[i][0]==0){
b[i]=1;
}
else if(a[i][1]==0&&a[i][0]==1){
b[i]=0;
}
}
}
if(flag==false||ans>=2) printf("-1\n");
else{
for(int i=0;i<n;i++){
printf("%d",b[i]);
}
printf("\n");
}
}
return 0;
}
G题 KFC Crazy Thursday
分析
求以‘k’或‘f’或‘c’为结尾的回文字符串的个数,就是简单的回文判断,不过数据量比较大,那么就分别记录K,F,C出现的位置,再通过判断前后出现的位置之差是不是偶数就可以初步筛选,再配合如果内部存在不是回文的一段,也可以排除一段,这样可以减少很多次循环,减少运行时间,算剪枝的一种
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[2000001],s1[2000001];
int len[2000001],n,num[2000001],fail[2000001],last,cur,pos,trie[2000001][26],tot=1;
int getfail(int x,int i)
{
while(i-len[x]-1<0||s[i-len[x]-1]!=s[i])x=fail[x];
return x;
}
int main()
{
int w;
while(cin>>w)
{
scanf("%s",s);
n=strlen(s);
for(int i=0;i<n;i++) s1[i]=s[i];
int a1=0,a2=0,a3=0;
fail[0]=1;len[1]=-1;
for(int i=0;i<=n-1;i++){
//if(i>=1)s[i]=(s[i]+last-97)%26+97;
pos=getfail(cur,i);
//找到cur的fail链中能匹配i位的最长回文后缀
if(!trie[pos][s[i]-'a']){
fail[++tot]=trie[getfail(fail[pos],i)][s[i]-'a'];
trie[pos][s[i]-'a']=tot;
len[tot]=len[pos]+2;
num[tot]=num[fail[tot]]+1;
}//不存在建立点,存在直接走过去
cur=trie[pos][s[i]-'a'];
last=num[cur];
if(s1[i]=='k') a1+=last;
if(s1[i]=='f') a2+=last;
if(s1[i]=='c') a3+=last;
//printf("%d ",last);
}
//cout<<endl;
cout<<a1<<" "<<a2<<" "<<a3<<endl;
}
return 0;
}
H题 Cutting Papers
分析
面积为圆的面积+阴影多边形圆外面的面积,即整个圆的面积+(四个三角形面积-半圆的面积)
代码如下
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pi 3.14159265358979
const int N=200010;
const int mod=1e9+7;
int a[N],b[N];
int cnta[N],cntb[N];
int sum[N];
signed main()
{
int n;
while(cin>>n)
{
double r=n/2.0;
printf("%.12lf\n",pi*r*r/2.0+2*r*r);
}
}
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pi 3.14159265358979
const int N=200010;
const int mod=1e9+7;
int a[N],b[N];
int cnta[N],cntb[N];
int sum[N];
signed main()
{
int n;
while(cin>>n)
{
double r=n/2.0;
printf("%.12lf\n",pi*r*r/2.0+2*r*r);
}
}
K题 Headphones
分析
可知一共有N对蓝牙耳机,Yasa拿走了k对耳机,那么剩下了N-k对耳机=2*(N-k)个耳机,如果要组成k+1对耳机,那么根据鸽巢原理,需要拿N-k+k+1->N+1个耳机保证能组成k+1对耳机,那么最少能组成k+1对耳机的条件就是剩下的耳机对数起码要有k+1对。
代码如下
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=200010;
const int mod=1e9+7;
int a[N],b[N];
int sum[N];
int n,k;
signed main()
{
while(cin>>n>>k)
{
if(2*k+1<=n)
{
int t=n-2*k-1;
cout<<(k+1)*2+t<<endl;
}
else cout<<-1<<endl;
}
}