感慨
这次题目又有了难度明显的提升
感谢
感谢lyj大佬 lk大佬 duny大佬!!!
A 春游(贪心)
首先可以计算一下发现实际上做33的车性价比是比较高的那么我们应该能做33就做33
你可能会问我们取一个33与49的公倍数,说不定做49的更好?
但是实际上即使这样还是33的花钱少!!!
这样我们有三种可能
①人数正好是33的倍数
全部做33的车
②人数余33小于等于16
那么少一辆33的多一辆49的
③人数余33大于16
多一辆33的
最终注意如果人数小于33特判一下即可
最终我们用了O(1)的时间解决了这个问题
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(0);
cout.tie(0);
cin.tie(0);
ll n;
cin>>n;
ll t=n%33;
if(n<33)
cout<<1900;
else if(t>0&&t<=16)
cout<<(n/33-1)*1900+3300;
else if(t>16)
cout<<(n/33+1)*1900;
else if(t==0)
cout<<(n/33)*1900;
}
B 斗地主IV(模拟)
这个不用说了吧,都会做,模拟一下就可以了
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll num[1000];
int main()
{
ios::sync_with_stdio(0);
cout.tie(0);
cin.tie(0);
ll n;
cin>>n;
while(n--)
{
ll ps,sc,cas;
cin>>ps>>sc>>cas;
if(cas==1)
{
for(int i=1;i<=4;i++)
if(ps==i)
num[i]+=sc*3;
else
num[i]-=sc;
}
else if(cas==2)
{
for(int i=1;i<=4;i++)
if(ps==i)
num[i]-=sc*3;
else
num[i]+=sc;
}
}
for(int i=1;i<=4;i++)
cout<<num[i]<<" ";
}
C BMI(语法基础)
注意用double去比较即可,如果不是good那么for暴力求解
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll num[10000];
int main()
{
ios::sync_with_stdio(0);
cout.tie(0);
cin.tie(0);
double h,w;
cin>>h>>w;
h/=100;
double t=w/pow(h,2);
if(t>=18&&t<=24)
cout<<"Good!";
else
{
if(t>24)
{
cout<<"Too fat!\n";
for(double i=w-1;i;i--)
{
double t1=(i)/pow(h,2);
if(t1<=24)
{
cout<<w-i;
break;
}
}
}
else if(t<18)
{
cout<<"Too thin!\n";
for(double i=w+1;;i++)
{
double t1=(i)/pow(h,2);
if(t1>=18)
{
cout<<i-w;
break;
}
}
}
}
}
D 人工智能(模拟)
这个题四个方向的车好说,皇后不好说。。。
皇后的斜向走还需要写4个函数
我比赛的时候昏迷了用了有标记就返回,实际上完全不需要这个条件
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int bk[2333][2333],mp[2333][2333];
int n;
void dfs1(int x,int y)
{
for(int i=x-1;i>=0;i--)
if(mp[i][y]==0)
bk[i][y]=1;
else if(mp[i][y]==1||mp[i][y]==2)
break;
for(int i=x+1;i<n;i++)
if(mp[i][y]==0)
bk[i][y]=1;
else if(mp[i][y]==1||mp[i][y]==2)
break;
for(int i=y-1;i>=0;i--)
if(mp[x][i]==0)
bk[x][i]=1;
else if(mp[x][i]==1||mp[x][i]==2)
break;
for(int i=y+1;i<n;i++)
if(mp[x][i]==0)
bk[x][i]=1;
else if(mp[x][i]==1||mp[x][i]==2)
break;
}
void dfs2(int x,int y)
{
if(x>=0&&y<n&&mp[x][y]==0)
bk[x][y]=1,dfs2(x-1,y+1);
else
return;
}
void dfs3(int x,int y)
{
if(x>=0&&y>=0&&mp[x][y]==0)
bk[x][y]=1,dfs3(x-1,y-1);
else
return;
}
void dfs4(int x,int y)
{
if(x<n&&y<n&&mp[x][y]==0)
bk[x][y]=1,dfs4(x+1,y+1);
else
return;
}
void dfs5(int x,int y)
{
if(x<n&&y>=0&&mp[x][y]==0)
bk[x][y]=1,dfs5(x+1,y-1);
else
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>mp[i][j];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(mp[i][j]==1)
bk[i][j]=1,dfs1(i,j);
else if(mp[i][j]==2)
bk[i][j]=1,dfs1(i,j),dfs2(i-1,j+1),dfs3(i-1,j-1),dfs4(i+1,j+1),dfs5(i+1,j-1);
int sum=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(!bk[i][j])
sum++;
cout<<sum;
}
E 基因锁(KMP)
比赛的时候有小bug,没有发现,后来询问duny大佬才发现了bug。。。。
思路就是kmp找染色的个数。然后遍历染色的部位一段一段的计算切点的个数
切点个数计算公式为
当前连续的染色个数/肥胖基因的长度
最后把切点加起来就可以了
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int nex[6666666],mk[6666666];
char a[6666666],b[6666666];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll n,m,sum=0,re=0,ans=0;
cin>>n>>m;
cin>>a+1>>b+1;
ll len1=strlen(a+1);
ll len2=strlen(b+1);
ll j=0,p=0;
for(int i=2;i<=len1;i++)
{
while(j&&b[i]!=b[j+1])
j=nex[j];
if(b[i]==b[j+1])
j++;
nex[i]=j;
}
j=0;
for(int i=1;i<=len1;i++)
{
while(j&&a[i]!=b[j+1])
j=nex[j];
if(a[i]==b[j+1])
j++;
if(j==len2)
{
for(int k=i-j+1;k<=i;k++)
mk[k]=1;
}
}
for(int i=0;i<=len1+1;i++)
if(mk[i]==1)
re++,ans++;
else if(mk[i]==0)
sum+=re/m,re=0;
cout<<ans<<" "<<sum;
}
F 量子计算(数学)
这个题好像是高中数学竞赛的真题来着
公式
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll n,m;
cin>>n>>m;
if(n%2==0)
{
ll t1=m-1;
t1%=10000007;
ll re=1;
for(int i=0;i<n;i++)
re*=(m-1)%10000007,re%=10000007;
ll ans=re+t1;
ans%=10000007;
cout<<ans;
}
else
{
ll t1=m-1;
t1%=10000007;
ll re=1;
for(int i=0;i<n;i++)
re*=(m-1)%10000007,re%=10000007;
ll ans=re-t1;
ans%=10000007;
cout<<ans;
}
}
G 常州拔河(贪心)
就是我课件里的上船问题
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
int sum,id;
}num[6666666];
bool cmp(node a,node b)
{
return a.sum==b.sum?a.id<b.id:a.sum<b.sum;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>num[i].sum,num[i].id=i+1;
sort(num,num+n,cmp);
int t=n/2;
cout<<n/2<<" ";
for(int i=0;i<n;i++)
{
cout<<num[i].id<<" ";
t--;
if(t==0)
break;
cout<<num[n-1-i].id<<" ";
t--;
if(t==0)
break;
}
}
H 常州买衣服(贪心)
既然优惠后一定价格小于等于原价,那么先对优惠后的价格进行一次排序,先买有优惠的。
再按照优惠前的排序,优惠券用光了买没有优惠的,注意不要买重了
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
int pre,now,id;
}num1[666666],num2[666666];
int bk[666666];
ll ans;
bool cmp1(node a,node b)
{
return a.now<b.now;
}
bool cmp2(node a,node b)
{
return a.pre<b.pre;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll n,k,m;
cin>>n>>k>>m;
for(int i=0;i<n;i++)
{
cin>>num1[i].pre>>num1[i].now;
num1[i].id=num2[i].id=i;
num2[i].pre=num1[i].pre;
num2[i].now=num1[i].now;
}
sort(num1,num1+n,cmp1);
sort(num2,num2+n,cmp2);
for(int i=0;i<k;i++)
{
m-=num1[i].now;
if(m>0)
ans++,bk[num1[i].id]=1;
else
break;
}
for(int i=0;i<n;i++)
{
if(!bk[num2[i].id])
{
m-=num2[i].pre;
if(m>0)
ans++,bk[num2[i].id]=1;
else
break;
}
}
cout<<ans;
}
I Domino(递推)
老生常谈的递推例题。。。应该都做过原题吧
公式
f[i]=f[i-1]+f[i-2]
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll num[10000];
int main()
{
ios::sync_with_stdio(0);
cout.tie(0);
cin.tie(0);
num[1]=1;
num[2]=2;
for(int i=3;i<=1000;i++)
num[i]=num[i-1]%1000000007+num[i-2]%1000000007,num[i]%=1000000007;
ll n;
cin>>n;
cout<<num[n];
}
J Block(不明)
待填坑
K Ring(不明)
待填坑
L StringII(思维)
总共四种情况
①如果上面的字符串中的字符小于下面的那么Impossible
②如果两个字符串长度相等,且不满足①那么Alice
③如果上面的字符串比下面的字符串长,且按顺序包含下面的那么Bob
④在③的条件上如果不按顺序包含那么就是Both
代码
#include <bits/stdc++.h>
using namespace std;
int bk1[300];
int bk2[300];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
string a,b;
int t;
cin>>t;
while(t--)
{
int f=0;
memset(bk1,0,sizeof(bk1));
memset(bk2,0,sizeof(bk2));
cin>>a>>b;
for(int i=0;i<a.size();i++)
bk1[a[i]-'a']++;
for(int i=0;i<b.size();i++)
bk2[b[i]-'a']++;
for(int i=0;i<26;i++)
if(bk1[i]<bk2[i])
{
f=1;
break;
}
if(f)
{
cout<<"Impossible\n";
continue;
}
if(a.size()==b.size())
cout<<"Alice\n";
else
{
int k=0;
for(int i=0;i<a.size();i++)
if(a[i]==b[k])
k++;
if(k==b.size())
cout<<"Bob\n";
else
cout<<"Both\n";
}
}
}