话说这期封面是真的好看....水一波博客了
考试总结
题目不难甚至有点水,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;
}