赛码解题报告(三)

装载乘客

题目描述

X学校最近组织了一场春游踏青活动,向Y公司租赁汽车运输学生。这次参加活动的总共有n个班级,第i班总共有ai名学生,每辆车最大乘车人数为m,满足m>a1, a2, ..., an。乘车时必须按照班级排列顺序进行乘车,不能调整班级顺序进行拼车。为保证同一个班级的学生在同一辆车上,如果当前汽车装完上一个班级后,下一个班级所有同学无法装下,那么当前车开走使用下一辆车。问最少需要多少辆车才能把所有学生运完?

输入

第一行数据是两个整数:n, m (1≤n,m≤100),n表示班级数目,m表示汽车最大装载人数。接下来n行是数据表示每个班级的人数数字a1, a2, ..., an (1≤ai≤m)。

样例输入

4 3

2 3 2 1


输出

输出需要的汽车数目。

样例输出

3

本题直接模拟即可,如果达到目标人数则选择下一辆车

#include
int main(){
    int n,m;
    int a[100];
    scanf("%d %d",&n,&m);
    for(int i=0;i         scanf("%d",&a[i]);
    int sum=1;
    int current=0;
    for(int i=0;i         if(current+a[i]>m){
            sum++;
            current=a[i];
        }
        else {
            current+=a[i];
        }
    }
    printf("%d\n",sum);
    return 0;
}



文艺青年爱文学


题目描述

小赛是一名文艺的程序员,他十分热爱文学。乘车去公司应聘的路上,小赛又在构想自己的诗歌了——

 

"啊!小赛啊小赛!帅啊很帅可帅了!

 啊!小赛啊小赛!棒啊很棒可棒了!

 啊!小赛啊小赛!啊啊啊啊啊啊啊!"

 

尽管小赛的诗歌——额……有那么一点——(啊啊别拦我——让我掐死这只小赛!)……

但是,小赛自己还是深深陶醉其中的。

 

小赛现在想要创作一首恰好为一定字数(共有n个能满足要求的字数,达到任一皆可)的新诗歌……

他会构想m种长度的短句(如上面那首“诗歌”,有长度为1和7的短句),构想每种长度的短句所耗费的时间是相同的。

现在让你帮忙算下,小赛最少需要多少时间,才能达成自己的目标呢?如果没有办法实现,请输出"It is not true!"(没有引号)。


输入

第一行一个整数n,表示小赛想创作诗歌的字数的集合大小。

接下来n行,其中第i行为一个数a[i],表示这首诗歌可以是a[i]个字。

第二行一个整数m,表示小赛可以构想出m种不同长度短句的个数。

接下来m行,其中第i行为两个整数b[i],c[i],其中b[i]表示小赛可以创作出长度为b[i]的短句,对应的c[i]表示创作这种长度短句所消耗的时间。

 

数据保证——a[]中的数各不相同,b[]中的数各不相同,c[]不超过10000.

数据保证——

对于30%的测试点,n=1,1<=m<=2,1<=a[],b[]<=20,

对于70%的测试点,1<=n,m<=5,1<=a[],b[]<=100;

对于100%的测试点,1<=n,m<=100,1<=a[],b[]<=10000;


样例输入

2

7

11

2

3 1

2 100


输出

输出一行,

如果有办法达成目标,则输出一个整数,表示达成目标所最少需要的创作时间。

如果没有办法达成目标,则输出"It is not true!"(没有引号)


本题比较复杂,没有想到很好的解决办法
动态规划逐个对与所给的长度求最小的,然后整体找到最小的。
动规问题一直掌握的不是很好。明天再看一遍~
#include
#include
#include
#include
using namespace std;
vector len,t;
const int MAX=2000000;
vector keep_dp(10001);
int dp(int x)
{
//if(x<0)return MAX;
if(!x)return 0;
if(keep_dp[x]>0)return keep_dp[x];
int smin=MAX;
for(int i=0;i {
if(x-len[i]>=0)
smin=min(smin,dp(x-len[i])+t[i]);
}
keep_dp[x]=smin;
return smin;
}


int main()
{
#ifdef H2
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n;
cin>>n;
vector req(n);
for(int i=0;i cin>>req[i];
int m;
cin>>m;
// len.resize(m);t.resize(n);
len.resize(m);t.resize(m);
for(int i=0;i cin>>len[i]>>t[i];
int smin=MAX;
//cout< for(int i=0;i {
smin=min(smin,dp(req[i]));
}
if(smin cout< else cout<<"It is not true!"<     return 0 ;
}

小赛的升级之路

题目描述

小赛经常沉迷于网络游戏。有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为a。在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3,…bn。如果遇到的怪物防御力bi小于等于小赛的当前能力值c,那么他就能轻松打败怪物,并且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi与c的最大公约数。那么问题来了,在一系列的锻炼后,小赛的最终能力值为多少?

输入

对于每组数据,第一行是两个整数n(1<=n<=100000)表示怪物的数量和a表示小赛的初始能力值,第二行n个整数,b1,b2..bn.(1<=bi<=n)表示每个怪物的防御力

数据保证——

50%的n<=100,

80%的n<=1000,

90%的n<=10000,

100%的n<=100000.


样例输入

3 50

50 105 200

5 20

30 20 15 40 100

    

输出

对于每组数据,输出一行。每行仅包含一个整数,表示小赛的最终能力值。


样例输出

110

205


本题也是较为简单,直接按题意求即可。注意最大公约数的求法。

#include
long long int gcd(long long int a,long long int b){


    long long int c=a%b;
    while(c!=0){
        a=b;
        b=c;
        c=a%b;
    }


    return b;
}
int main(){
    long long int n,a,c,current;
    while(scanf("%lld %lld",&n,&a)!=EOF){
    current=a;
    for(int i=0;i         scanf("%lld",&c);
        if(c<=current){
            current+=c;
        }else {
            current+=gcd(c,current);
        }
    }
    printf("%lld\n",current);
    }
    return 0;
}


超时购物

题目描述

小赛特别爱购物,有一次他获得了在超市免费购物的机会,超市内有n件物品,第i(1<=i<=n)件物品的价值为ai,但是他能拿的物品的价值总和不能超过V。贪心的小易希望能拿尽量多数量的物品,那么请你帮他计算下他最多能拿到多少件物品?

输入

对于每组数据,第一行是两个整数n(1<=n<=100000)表示物品的数量和V(1<=V<=1000000),表示小易最多能拿的总价值,第二行n个整数,a1,a2..an.(1<=ai<=1000)表示每个物品的价值

数据保证——

50%的n<=1000,

80%的n<=10000,

100%的n<=100000.


样例输入

3 50      

50 105 200

5 55

30 20 20 40 100


输出

对于每组数据,输出一行。每行仅包含一个整数,表示小易最多能拿到的物品数量。


样例输出

1

2

最初看题目时以为是动规问题,其实很简单,先对所有物品的价值排序,从最小价值的开始取,直到不能再取为止

#include
#include
int cmp(const void *a,const void *b){
    if(*(int *)a>*(int *)b)
        return 1;
    else return -1;
}
int main(){
    int n,a;
    int m[100000];
    while(scanf("%d %d",&n,&a)!=EOF){
        for(int i=0;i             scanf("%d",&m[i]);
        }
        qsort(m,n,sizeof(int),cmp);
        int total=0;
        int countx=0;
        int i=0;
            while(total+m[i]                 total+=m[i];
                countx++;
                i++;
            }
            printf("%d\n",countx);


    }
    return 0;
}


投篮游戏

题目描述

小赛最近迷上了篮球,报名参加一个投篮游戏。球场有p个篮筐,编号为0, 1, ..., p-1,每个篮筐下面有个袋子,每个袋子最多能装入一个篮球。现在有n个篮球,第i个篮球有一个数字xi,投篮规则是将数字为xi的篮球,投入篮筐编号为xi除以p所得的余数。如果袋子里面已经有球,那么篮球就会弹出,投篮游戏结束,输出i;否则重复进行将篮球投完,游戏结束,输出-1。问小赛会在何时结束游戏?


输入

第一行数据是两个整数:p, n (2≤p,n≤300),p表示篮筐数目,n表示篮球数目。接着n行数据表示篮球上的数字xi (0≤xi≤109)。

样例输入

10 5

0

21

53

41

53


输出

输出投篮游戏结束时输出结果。


样例输出

4

本题也是直接按题意求即可

#include
int flag[300];
long long int c[301];
int main(){
    long long int p,n;
    scanf("%lld %lld",&p,&n);
    for(int i=0;i         flag[i]=0;
    }


    for(int i=1;i<=n;i++){
        scanf("%lld",&c[i]);
    }
    int k=0;
       for(int i=1;i<=n;i++){
        if(flag[c[i]%p]==1){
            printf("%d\n",i);
            k=1;
            break;
        }
        else{
            flag[c[i]%p]=1;
        }
    }
    if(k==0)
        printf("-1\n");
    return 0;
}

你可能感兴趣的:(赛码)