5.9考试总结

话说这期封面是真的好看....水一波博客了

考试总结

题目不难甚至有点水,3个dalao都AK了,一片200多分的也证明了题目不难了,咕咕咕

理想分数:300

实际分数:300

考试中出现的问题:

第二题一开始读题不清,导致浪费了30分钟左右

下面是题目分析:

多重背包

(backpack.cpp/c/pas)
(1s/256M)

题目描述
提供一个背包,它最多能负载重量为W的物品。
现在给出N种物品:对于第i类物品,一共有Ci件物品;对于每一件物品,重量为Wi,价值为Vi。
找出一种装载方式使得背包中的物品总价值最大。

输入格式(backpack.in)
第一行两个整数N,W,代表物品的种类与背包的总负重。
第2~N+1行,每行三个整数Wi, Vi, Ci,代表第i种物品的重量、价值与数量。

输出格式(backpack.out)
仅一行,一个整数V,代表最大的总价值。

样例输入
3 9
5 8 2
3 6 2
2 1 5

样例输出
14

数据范围与限制
1<=N<=20, 0<=W<=1000
1<=Wi<=100, 0<=Vi<=100, 0<=Ci<=100

思路:

这题目您还敢在直白一些吗?这不就是个板子题吗?
可以去看我之前的博客--背包问题

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
#define ll long long int
const int MAXN=2200;
using namespace std;
const int maxn=999999999;
const int minn=-999999999;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int n,m,w[MAXN],c[MAXN],sum[MAXN],f[MAXN];
int main()
{
    freopen("backpack.in","r",stdin);
    freopen("backpack.out","w",stdout);
    n=read(),m=read();//n m代表物品的种类与背包的总负重
    for(int i=1;i<=n;++i)
    {
        w[i]=read();
        c[i]=read();
        sum[i]=read();
    }
    for(int i=1;i<=n;++i) //种类
    {
        for(int j=m;j>=0;--j)
        {
            for(int k=0;k<=sum[i];++k)
            {
                if(j-k*w[i]>=0)
                {
                    f[j]=max(f[j],f[j-k*w[i]]+k*c[i]);
                }
            }
        }
     } 
     cout<<f[m];
    return 0;
}

循环序列

(circulate.cpp/c/pas)
(1s/256M)

题目描述
Alice与Bob在玩游戏:
Alice首先给出两个数X与Y(X<=Y);
Bob则按顺序将X,X+1,X+2,…,Y-1,Y写成一个大数S。
Alice最后将S首尾相连,让其围成一个圈。
这时,Bob想知道,从S的开头出发,往后的第L位到第R位数字之和是多少。

输入格式(circulate.in)
第一行四个整数X,Y,L,R,代表Alice的两个数字和Bob想要知道的第L位到第R位的数字之和。

输出格式(circulate.out)
仅一行,一个整数M,代表第L位到第R位的数字之和。

样例输入
10 11 4 12

样例输出
7

样例解释
Bob将数字写成一行大数S = 1011;围成一个圈后,从第4位到第12位分别是1,1,0,1,1,1,0,1,1,它们的和是7.

数据范围与限制
对于50%的数据,L=1, X,Y,L,R<=1000;
对于100%的数据,S的长度不大于10000,X,Y,L,R<=100000000.

思路

这道题应该是这次考试较难的一道,其实也是很简单的那种,可能是我一看就觉得是用前缀和,所有就轻松一点吧....
其实这题想到前缀和一点都不难啊,这题时间浪费在你的计算和上了,所以用前缀和.

int calc(int x) {//统计和 
    return x/ans1*a[ans1]+a[x%ans1];
}

这样就可以避免重复计算了,其实时间也浪费在重复计算上了

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
#define ll long long int
using namespace std;
const int maxn=999999999;
const int minn=-999999999;
const int MAXN=10005;
inline int read() {
    char c = getchar();
    int n = 0, f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') n = n * 10 + c - '0', c = getchar();
    return n * f;
}
int n,m,l,r,a[MAXN],ans1=1,b[MAXN],ans2=1;
int calc(int x) {//统计和 
    return x/ans1*a[ans1]+a[x%ans1];
}
int main() {
//  freopen("circulate.in","r",stdin);
//  freopen("circulate.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&l,&r);
    for(int i=n; i<=m; i++) {
        int p=i;
        ans2=1;
        while(p!=0) {
            b[ans2++]=p%10;
            p=p/10;
        }
        for(int i=ans2-1; i>=1; i--) {
            a[ans1++]=b[i];
        }
    }
    ans1--;
    for(int i=1; i<=ans1; i++) {//前缀和 
        a[i]=a[i-1]+a[i];
    }
    cout<<calc(r)-calc(l-1);
    return 0;
}

合并游戏

merge.cpp/c/pas
(1s/256M)

题目描述
Cindy和Dan在玩一个游戏。
一开始Cindy想出了N个数,接着她把这N个数全部给了Dan。
Dan得到这组数后,它会挑出3个数(如果不足3个则全部挑出)。Dan会把这几个数加起来变成一个数,然后再把这个数与剩下的数再放到一起。Dan会一直这样做,直到最后只剩下一个数。
Cindy则会在旁边记下每次Dan得到的数,她把这些数加起来,作为本次游戏的得分。她想知道,对于一组数,Dan能得到的最大的得分是多少?

输入格式
第一行一个正整数N,代表这组数的个数;
第二行N个正整数,代表这N个整数。

输出格式
一行一个整数,代表可能的最大得分。

样例输入(merge.in)
4
3 1 5 6

样例输出(merge.out)
29

样例解释
Dan可以首先把(3,5,6)这三个数先合并起来,得到3 + 5 +6 = 14;接着他把剩下的两个数再合起来,得到1+14=15.这样,总得分是最大的 14 + 15 = 29.

数据范围与限制
对于50%的数据,N<=10
对于100%的数据,N<=1000,所有数不大于1000

思路:

这题超级水,不解释了,贪心就ok了

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<cstring>
#define ll long long int
using namespace std;
const int maxn=999999999;
const int minn=-999999999;
inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int n,ans;
priority_queue<int>q;
int main() {
    freopen("merge.in","r",stdin);
    freopen("merge.out","w",stdout);
    int n=read();
    for(int i=1; i<=n; ++i) {
        int x=read();
        q.push(x);
    }
    while(q.size()!=1) {
        int tot=0;
        for(int i=1; i<=3; ++i) {
            if(!q.empty()) {
                tot+=q.top();
                q.pop() ;
            }
        }
        q.push(tot);
        ans+=tot;
    }
    cout<<ans;
    return 0;
}

转载于:https://www.cnblogs.com/pyyyyyy/p/10841194.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值