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;
}

posted @ 2019-05-09 21:30  pyyyyyy  阅读(239)  评论(5编辑  收藏  举报