K Headphones
题意
一天,尼奥的家停电了。所以他和他的妹妹Yasa想从抽屉里拿一些耳机。在黑暗中,如果他们随机拿了一些耳机,而Yasa已经拿出了k副耳机。NIO要带多少副耳机才能保证比妹妹多拿几副,也就是k+1副耳机。假设抽屉里有N副耳机,每副都不一样。
思路
本题应该考虑最不理想的情况,他拿了n-k+1+k个耳机时,可以确保里边有1+k对耳机。
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define int long long
using namespace std;
typedef long long ll;
int n,k;
int main()
{
IOS;
while(cin>>n>>k)
{
if(n-k>k)
{
cout<<(n-k+1+k)<<endl;
}
else
{
cout<<"-1"<<endl;
}
}
return 0;
}
C Bit Transmission
题意
有个01组成的字符串,对某些位置询问是否是1,询问3n次,有至多一次询问返回的答案是错误的,问这些询问结果能否唯一确定字符串。
思路
所有询问一共只能发生一次错误,因而在所有的询问中,0的数量大于1的数量的输出0,1的数量大于0的数量的输出1,0的数量等于1的数量的机器坏了,错误次数多于1的也是机器坏了。
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define int long long
using namespace std;
typedef long long ll;
int a[100005][2];
string temp;
int main()
{
IOS;
int n;
int i,j,k;
int t;
int shu;
char s[5];
while(cin>>n)
{
temp="";
memset(a,0,sizeof(a));
t=3*n;
while(t--)
{
cin>>shu>>s;
if(s[0]=='Y')
{
a[shu][1]++;
}
else if(s[0]=='N')
{
a[shu][0]++;
}
}
int cuo=0;
for(i=0;i<n;i++)
{
if(cuo>1)
break;
if(a[i][0]>a[i][1])
{
temp+='0';
cuo+=a[i][1];
}
else if(a[i][0]<a[i][1])
{
temp+='1';
cuo+=a[i][0];
}
else if(a[i][0]==a[i][1])
break;
}
if(i!=n)
cout<<"-1\n";
else
cout<<temp<<endl;
}
return 0;
}
H Cutting Papers
题意
NIO和他四岁的小妹妹Yasa正在剪纸。NIO画了几条线段,得到一个封闭的区域,一个多边形,从一个数学不等式,∣x∣+∣y∣+∣x+y∣≤n。和Yasa画了一个圆,这个圆的中心与NIO画的多边形的中心重合,圆的半径是nn的一半。他们想切割出多边形和圆形的结合区域。假设他们玩基于无限纸的切割游戏。他们从纸上剪下的面积有多大?即求圆形和多边形的并集。
思路
将不等式转换为平面直角坐标系上的图形,再与圆取并集。
通过数学计算方法可得圆形于阴影部分的面积并集为(n/2)^2*(2+pi/2),因为本题精度有要求,pi取值应较为精细。可用acos(-1)来表示pi。
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
typedef long long ll;
const double pi=acos(-1);
signed main()
{
IOS;
int n;
while(cin>>n)
{
cout<<fixed<<setprecision(9)<<(n/2.0)*(n/2.0)*(2+pi/2.0)<<endl;
}
return 0;
}
G KFC Crazy Thursday
题意
一天,尼奥在他的电脑上发现了一封来自他的朋友卡拉的电子邮件。他打开邮件,发现一张图片,上面有一大串26个小写字母。他问卡拉为什么给他寄这张照片。Kala说这是他给NIO的一个挑战:如果NIO能算出以“k”、“f”和“c”结尾的回文数,他会给NIO买一份肯德基套餐。聪明的NIO打开了一个人工智能软件,将图像上的所有字母转换成一个文本文件。NIO承诺,如果你能帮助他,他将与你分享肯德基套餐。
思路
采用manacher算法进行计算
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
int numk[4000005]={0};
int numf[4000005]={0};
int numc[4000005]={0};
char s[4000005];
char s1[4000005];
int p[4000005];//p[i]记录s[i]能单侧延伸多长
int manacher()
{
int r=0;//最右边界
int c=0;//中心
int len=strlen(s);
int ans=0;
for(int i=1;i<len;i++)
{
if(i<r)
{
p[i]=min(r-i,p[2*c-i]);
numk[i]+=numk[2*c-i];
numf[i]+=numf[2*c-i];
numc[i]+=numc[2*c-i];
if(r-i<p[2*c-i])
{
for(int j=r-i;j<=p[2*c-i];j++)
{
if(s[2*c-i+j]==s[2*c-i-j])
{
if(s[2*c-i+j]=='k')
numk[i]--;
if(s[2*c-i+j]=='f')
numf[i]--;
if(s[2*c-i+j]=='c')
numc[i]--;
}
}
}
}
else
{
p[i]=1;
}
while(s[i+p[i]]==s[i-p[i]])
{
if(s[i+p[i]]=='k')
numk[i]++;
if(s[i+p[i]]=='f')
numf[i]++;
if(s[i+p[i]]=='c')
numc[i]++;
p[i]++;
}
if(i+p[i]>r)
{
r=i+p[i];
c=i;
}
ans=max(ans,p[i]);
}
return ans-1;
}
signed main()
{
IOS;
int n;
cin>>n;
int i,j,k;
cin>>s1;
j=0;
//预处理
for(i=0;s1[i]!=0;i++)
{
s[++j]='#';
s[++j]=s1[i];
}
s[0]='%';
s[++j]='#';
s[++j]=0;
manacher();
int sumk=0;
int sumf=0;
int sumc=0;
for(i=0;i<=j;i++)
{
sumk+=numk[i];
sumf+=numf[i];
sumc+=numc[i];
if(s[i]=='k')
sumk++;
if(s[i]=='f')
sumf++;
if(s[i]=='c')
sumc++;
}
cout<<sumk<<" "<<sumf<<" "<<sumc<<endl;
return 0;
}
B Watches
题意
尼奥是这家钟表店的老板。一天,他想从工厂购买一批手表。然而,他住在一个征收重税的国家。如果他买了k个手表,他单子上的第一只手表就要花掉他(ai(原价)+k×i)美元(原列表中第i个)。现在NIO只有M美元,所以NIO问你他实际上可以购买多少块手表。
思路
采用二分的思想,在1到n上二分确定k的值,再对整体按k处理后进行排序,求得1到k的总价值是否在m以内,进而求出最后的合适的数量。
代码
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
struct node
{
int val;
int xu;
}pos[100005];
int n,m;
int mid;
bool cmp(node a,node b)
{
return a.val+mid*a.xu<b.val+b.xu*mid;
}
bool check(int mid)
{
int ans=0;
sort(pos+1,pos+n+1,cmp);
for(int i=1;i<=mid;i++)
{
ans+=pos[i].val+mid*pos[i].xu;
if(ans>m)
return false;
}
return true;
}
signed main()
{
IOS;
cin>>n>>m;
int i,j,k;
for(i=1;i<=n;i++)
{
cin>>pos[i].val;
pos[i].xu=i;
}
int sum=0;
int l=0;
int r=n;
while(l<r)
{
mid=(l+r+1)/2;
if(check(mid))
l=mid;
else
r=mid-1;
}
cout<<l<<endl;
return 0;
}