zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    通信原理
    java实现聊天室的简单实现
    计算机网络笔记——第四章、网络层
    泛型高级之通配符
    看文档总结
    HashSet源码解析
    HashTable源码解析
    计算机网络笔记——第三章、数据链路层
    Collection集合的功能
    第六章 应用层
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/10841194.html
Copyright © 2011-2022 走看看