Problem A: 跑跑卡丁车系列之游戏下载
Time Limit: 1000 MS Memory Limit: 257792 KB
64-bit interger IO format: %lld Java class name: Main
某天,金斌在实验室玩跑跑卡丁车,众多群巨也一起加入其中。蛋蛋发现这是一个虐爆群巨的好机会,所以他也准备去下载游戏了!
但是由于不可抗力的原因,113的网速灰常快(man),所以每个群巨都有一个ai值。如果群巨当前网速小于这个值,那么群巨就会小情绪!!!
现在给出当前网速x,问有多少人没有小情绪。(假设:每个人都是x)
Input
测试数据有多组,每组输入一个N ( N <= 1e8 ),下一行输入N个数 ,表示每个人的ai值 ( ai < 1000)。接着输入一个Q( 1<= Q <=1e5),表示有Q个询问。每个询问输出一个数字。
Output
对于每个询问输出,在当前状态下,有多少人没有小情绪。
Sample Input
6
1 2 3 4 5 6
3
2
3
7
Sample Output
2
3
6
第一题没啥好用算法的,直接使用stl的upper_bound来求出大于等于这个数的下标。不过要先把数组排好序。
#include "iostream"
#include "string.h"
#include "algorithm"
using namespace std;
const int maxn = 100000+5;
int num[maxn];
int m;
int qus;
int ans;
int main(){
int n;
while(~scanf("%d",&n)){
for( int i=0 ; i<n ; i++ ){
scanf("%d",&num[i]);
}
sort(num,num+n);
scanf("%d",&m);
while(m--){
scanf("%d",&qus);
ans = upper_bound(num,num+n,qus)-num;
printf("%d\n",ans);
}
}
return 0;
}
Problem C: 跑跑卡丁车系列之登入密码——v2.0
Time Limit: 2000 MS Memory Limit: 128896 KB
64-bit interger IO format: %lld Java class name: Main
经过很长一段时间后,蛋蛋终于成功地安装好了游戏。由于蛋蛋太优秀了,他有好多的帐号,与之对应的就有好多的密码。突然他忘记了帐号所对应的密码。但没关系,在一段不可描述的操作之后,蛋蛋成功的想起了密码。突然他发现,原来的密码缺乏美感。所以他准备添加一些字母把密码改成一个回文串,由于金斌要开车了,蛋蛋想尽快解决这个问题,然后去虐爆金斌。所以他想知道最少要加多少个字母?
这个问题有两个版本。v1.0是小数据版本,v2.0是大数据版本。通过2.0的代码,肯定可以通过1.0。
Input
输入数据有多组,每组包含一个字符串长度(|S| < 5000 ),数据保证只含有小写字母
Output
最少应该加多少个字母
Sample Input
abba
caab
Sample Output
0
2
我们直接做大数据版本的题目,这个题目就是给你一个字符问再添加几个字符能构成 123454321 这样的回文。
直接用这个字符串与它的反转字符串求出最大公共子串。将它的长度减去这个公共子串的长度就是我们需要添加的字母的个数。
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int maxn = 1e4+5;
char str1[maxn],str2[maxn];
int dp[2][maxn];
int main()
{
while(~scanf("%s",str1+1)){
int n = strlen( str1+1 );
for( int i = 1; i <= n; i++ ) str2[i] = str1[n-i+1];
memset(dp,0,sizeof(dp));
for( int i = 1; i <= n; i++ ){
int u = i%2;
int v = (i-1)%2;
for( int j = 1; j <= n; j++ ){
if( str1[i] == str2[j] )
dp[u][j] = dp[v][j-1] + 1;
else
dp[u][j] = max( dp[u][j-1],dp[v][j]);
}
}
printf("%d\n",n-dp[n%2][n]);
}
return 0;
}
Problem E: 跑跑卡丁车系列之开齿轮——v2.0
Time Limit: 1000 MS Memory Limit: 257792 KB
64-bit interger IO format: %lld Java class name: Main
蛋蛋登入游戏后发现,因为是回归玩家,系统送了他两辆车。但是蛋蛋非常嫌弃,直接开始虐金斌。跑了几局之后,蛋蛋果然虐爆的整个实验室。这时,任务窗口提示,蛋蛋获得了balabala材料。蛋蛋进入他的小屋发现,合成一个齿轮需要N个材料,每种材料需要ai个,蛋蛋仔细的搜索了他的仓库发现每种材料他已经有了bi个。蛋蛋当然不会浪费材料,所以他使用了一种不可描述的技能,可以直接获得一个某种材料。但是因为使用这种黑科技需要一定的体力,所以蛋蛋最多只能使用K次。问蛋蛋最多可以开多少个齿轮。
(v1.0是小数据版本,v2.0是大数据版本。通过2.0的代码,一定可以通过1.0)
Input
输入数据有多组,每组第一行包括两个整数N和K( 1 <= N <= 100 000, 1 <= K <= 1e9 ),N和K的意思如题所描述。第二行有N个整数表示合成一个齿轮所需要的材料ai( 1 <= ai <= 1e9 )。第三行有N个整数表示已经有的材料bi( 1<= bi <= 1e9 )
Output
输出蛋蛋最多可以开多少个齿轮
Sample Input
1 1000000000
1
1000000000
10 1
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
1 1 1 1 1 1 1 1 1 1
Sample Output
2000000000
0
这题我们不能用已知条件去推出齿轮个数,这样不仅困难还容易爆炸。我们采用二分法二分齿轮个数并且当它增加的齿轮等于k值就弹出符合的齿轮个数
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
typedef long long ll;
using namespace std;
const int maxn = 1e5+5;
ll need[maxn],num[maxn];
ll n,k;
ll serch( ll l,ll r ){
while( l<=r ){
ll mid = (l+r)/2;
ll sum = 0;
for( int i=0 ; i<n ; i++ ){
if( num[i] < need[i]*mid ){
sum += need[i]*mid-num[i];
if(sum>k) break;
}
}
if( sum==k ) return mid;
if( sum<k ) l=mid+1;
else r=mid-1;
}
return l-1;
}
int main(){
while(scanf("%lld%lld",&n,&k)!=EOF){
for( int i=0 ; i<n ; i++ ){
scanf("%lld",&need[i]);
}
for( int i=0 ; i<n ; i++ ){
scanf("%lld",&num[i]);
}
ll ans = serch(0,2e9+5);
printf("%lld\n",ans);
}
return 0;
}
Problem G: 跑跑卡丁车系列之排车位——v2.0
Time Limit: 1000 MS Memory Limit: 257792 KB
64-bit interger IO format: %lld Java class name: Main
在开了无数个齿轮之后,蛋蛋决定在小屋内给这些车排个顺序。他天真地认为:任意两辆车不在同一行,同一列就很美观。为了简化问题,我们把蛋蛋的小屋看成是一个N*N的方格,蛋蛋有K辆车要排。在之前的过程中,他因为使用太多不可描述的技能,已经无法思考了。请你告诉他一共有多少种方案。
Input
输入数据有多组,每组两个整数N和K,(1 <=N,K <= 30)
Output
输出有多少种方案,答案保证小于1e17
Sample Input
1 1
2 1
3 1
4 1
4 2
4 3
4 4
4 5
Sample Output
1
4
9
16
72
96
24
0
找规律,用二维数组打表
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
typedef long long LL;
const LL maxn = 1e17;
LL dp[31][31];
LL n,k;
int main(){
LL ans;
while(scanf("%lld%lld",&n,&k)!=EOF){
LL fz = n*n;
LL fm = 1;
LL cnt = 2;
/*while(k!=1){
n--;
fz *= n*n;
fm *= cnt;
cnt++;
k--;
}
ans = fz/fm;
cout<<"fz "<<fz<<endl;
cout<<"fm "<<fm<<endl;
cout<<ans<<endl;*/
for( int i=0 ; i<=30 ; i++ ){
for( int j=0 ; j<=30 ; j++ ){
dp[i][j]=1;
}
}
for( int i=0 ; i<=30 ; i++ ){
for( int j=1 ; j<=i ; j++ ){
dp[i][j] = (dp[i-1][j-1]*i*i/j);
}
}
if(k>n) puts("0");
else
printf("%lld\n",dp[n][k]);
}
return 0;
}
然后,美辰巨的题目做不出来~~~
我真菜啊。