2016年暑假集训周赛#1
周赛链接
Problem A:跑跑卡丁车系列之游戏下载
思路:先排序,然后用upper_bound返回大于的第一元素
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int a[10000010];
int main()
{
int n,Q,x;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n); //排序
scanf("%d",&Q);
while(Q--)
{
scanf("%d",&x);
printf("%d\n",upper_bound(a,a+n,x)-a); //返回大于的第一个元素
}
}
return 0;
}
Problem B:跑跑卡丁车系列之登入密码----v1.0
思路:将字符串翻转,求最长公共子序列,再用长度减去这个序列长度
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[510][510];
string s1,s2;
int main()
{
while(cin>>s1)
{
s2=s1;
reverse(s2.begin(),s2.end()); //翻转
memset(dp,0,sizeof(dp)); //初始化
int l=s1.length();
for(int i=1;i<=l;i++)
{
for(int j=1;j<=l;j++)
{
if(s1[i-1]==s2[j-1])
dp[i][j]=dp[i-1][j-1]+1; //求最长公共子序列
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
printf("%d\n",l-dp[l][l]); //用长度减去最长公共子序列
}
return 0;
}
Problem C:跑跑卡丁车系列之登入密码----v2.0
思路:利用滚动数组
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[2][5050];
char s1[5001],s2[5010];
int main()
{
while(~scanf("%s",s1))
{
memset(dp,0,sizeof(dp));
int l=strlen(s1);
for(int i=l-1;i>=0;i--)
s2[l-i-1]=s1[i];
s2[l]='\0';
int ans=0;
for(int i=1;i<=l;i++)
{
for(int j=1;j<=l;j++)
{
if(s1[i-1]==s2[j-1])
dp[i%2][j]=dp[(i-1)%2][j-1]+1; //滚动数组
else
dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]);
if(dp[i%2][j]>ans)
ans=dp[i%2][j]; //存最大值 ,最长公共子序列
}
}
printf("%d\n",l-ans); //长度减去最长公共子序列长度
}
return 0;
}
Problem D/E:跑跑卡丁车系列之开齿轮----v1.0/2.0
思路:用二分搜索答案
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
long long n,k,m,sum,a[100010],b[100010];
long long search(long long l,long long r)
{
while(l<=r)
{
m=(l+r)/2;
sum=0;
for(int i=1;i<=n;i++) //遍历每种材料是否满足
{
if(a[i]*m>b[i])
sum+=(a[i]*m-b[i]);
if(sum>k)
break;
}
if(sum==k)
return m;
else if(sum<k)
l=m+1;
else
r=m-1;
}
return r;
}
int main()
{
while(~scanf("%lld%lld",&n,&k))
{
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
scanf("%lld",&b[i]);
printf("%lld\n",search(1,2000000002)); //最多可以做这么多蛋糕
}
return 0;
}
Problem F:跑跑卡丁车系列之排车位----v1.0
思路:找规律,每次取模
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
long long a[32][32];
#define INF 1000000007
int main()
{
for(int i=1;i<=30;i++)
{
for(int j=1;j<=i;j++)
{
if(j==1)
a[i][j]=(i*i);
else
a[i][j]=(a[i][1]*a[i-1][j-1]/j%INF);
}
}
while(~scanf("%d %d",&n,&m))
{
printf("%lld\n",a[n][m]);
}
return 0;
}
Problem G:跑跑卡丁车系列之排车位----v2.0
题目大意 :同上
思路:上一题去掉取模.
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
long long a[32][32];
#define INF 1000000007
int main()
{
for(int i=1;i<=30;i++)
{
for(int j=1;j<=i;j++)
{
if(j==1)
a[i][j]=i*i;
else
a[i][j]=(a[i][1]*a[i-1][j-1]/j);
}
}
while(~scanf("%d %d",&n,&m))
{
printf("%lld\n",a[n][m]);
}
return 0;
}
美辰的水题:
Problem H:方巨的数学题_v1Problem I:方巨的数学题_v2