• 19.05.09 解题报告


    预计得分:100+50+100=250

    实际得分:5+50+0=55

    发下试题,看了一遍三个题:
    T1 sb题、裸的背包
    T2 我可以模拟。。
    T3 sb题、贪心、优先队列

    T1 多重背包

    (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

    我是真的服我自己,好好的多重背包不写,偏偏要逞能,写个多重转01背包,得个5分让自己乐呵乐呵???(我是**嘛??)

    AC代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int N,W;
    
    #define MAXN 1111
    
    int w[MAXN],v[MAXN],c[MAXN];
    
    inline int read() {
    	int x=0,f=1;
    	char c=getchar();
    	for(; !isdigit(c); c=getchar()) if(c=='-') f=-1;
    	for(;  isdigit(c); c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    
    int f[MAXN];
    
    int main() {
    	freopen("backpack.in","r",stdin);
    	freopen("backpack.out","w",stdout);
    	cin>>N>>W;
    	for(int i=1; i<=N; i++)
    		cin>>w[i]>>v[i]>>c[i];
    	for(int i=1; i<=N; i++)
    		for(int j=1; j<=c[i]; j++)
    			for(int k=W; k>=w[i]; k--)
    				f[k]=max(f[k],f[k-w[i]]+v[i]);
    	cout<<f[W];
    	return 0;
    }
    

    T2 循环序列

    (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.

    考试的时候,蹦出来的第一个思路是**模拟(记录+建环),看了眼数据范围,觉得很骚,但是又没有想到更好的,于是……

    Code:(码风鬼畜)

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    #define N 100000011
    
    char S[N];
    
    int X,Y,L,R;
    
    inline int read() {
    	int x=0,f=1;
    	char c=getchar();
    	for(; !isdigit(c); c=getchar()) if(c=='-') f=-1;
    	for(;  isdigit(c); c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    
    int cnt=0;
    
    int ans=0;
    
    int main(void) {
    	freopen("circulate.in","r",stdin);
    	freopen("circulate.out","w",stdout);
    	X=read();
    	Y=read();
    	L=read();
    	R=read();
    	for(int i=X; i<=Y; i++) {
    		if((i/10)==0) {
    			S[cnt++]=(char)i;
    		} else if((i/10<10) && (i/10>0)) {
    			S[cnt++]=(char)(i/10);
    			S[cnt++]=(char)(i%10);
    		} else if((i/100<10) && (i/100>0)) {
    			S[cnt++]=(char)(i/100);
    			S[cnt++]=(char)(i%100/10);
    			S[cnt++]=(char)(i%10);
    		} else if((i/1000<10) && (i/1000>0)) {
    			S[cnt++]=(char)(i/1000);
    			S[cnt++]=(char)(i%1000/100);
    			S[cnt++]=(char)(i%100/10);
    			S[cnt++]=(char)(i%10);
    		} else if((i/10000<10) && (i/10000>0)) {
    			S[cnt++]=(char)(i/10000);
    			S[cnt++]=(char)(i%10000/1000);
    			S[cnt++]=(char)(i%1000/100);
    			S[cnt++]=(char)(i%100/10);
    			S[cnt++]=(char)(i%10);
    		} else if((i/100000<10) && (i/100000>0)) {
    			S[cnt++]=(char)(i/100000);
    			S[cnt++]=(char)(i%100000/10000);
    			S[cnt++]=(char)(i%10000/1000);
    			S[cnt++]=(char)(i%1000/100);
    			S[cnt++]=(char)(i%100/10);
    			S[cnt++]=(char)(i%10);
    		} else if((i/1000000<10) && (i/1000000>0)) {
    			S[cnt++]=(char)(i/1000000);
    			S[cnt++]=(char)(i%1000000/100000);
    			S[cnt++]=(char)(i%100000/10000);
    			S[cnt++]=(char)(i%10000/1000);
    			S[cnt++]=(char)(i%1000/100);
    			S[cnt++]=(char)(i%100/10);
    			S[cnt++]=(char)(i%10);
    		} else if((i/10000000<10) && (i/10000000>0)) {
    			S[cnt++]=(char)(i/10000000);
    			S[cnt++]=(char)(i%10000000/1000000);
    			S[cnt++]=(char)(i%1000000/100000);
    			S[cnt++]=(char)(i%100000/10000);
    			S[cnt++]=(char)(i%10000/1000);
    			S[cnt++]=(char)(i%1000/100);
    			S[cnt++]=(char)(i%100/10);
    			S[cnt++]=(char)(i%10);
    		} else if((i/100000000<10) && (i/100000000>0)) {
    			S[cnt++]=(char)(i/100000000);
    			S[cnt++]=(char)(i%100000000/10000000);
    			S[cnt++]=(char)(i%10000000/1000000);
    			S[cnt++]=(char)(i%1000000/100000);
    			S[cnt++]=(char)(i%100000/10000);
    			S[cnt++]=(char)(i%10000/1000);
    			S[cnt++]=(char)(i%1000/100);
    			S[cnt++]=(char)(i%100/10);
    			S[cnt++]=(char)(i%10);
    		}
    	}
    	int opt=cnt-1;
    	for(int i=0; i<cnt; i++) {
    		S[++opt]=S[i];
    	}//2
    	for(int i=0; i<2*cnt; i++) {
    		S[++opt]=S[i];
    	}//4
    	for(int i=0; i<4*cnt; i++) {
    		S[++opt]=S[i];
    	}//8
    	for(int i=0; i<8*cnt; i++) {
    		S[++opt]=S[i];
    	}//16
    	for(int i=0; i<16*cnt; i++) {
    		S[++opt]=S[i];
    	}//32
    	for(int i=0; i<32*cnt; i++) {
    		S[++opt]=S[i];
    	}//64
    	for(int i=0; i<64*cnt; i++) {
    		S[++opt]=S[i];
    	}//128
    	for(int i=0; i<128*cnt; i++) {
    		S[++opt]=S[i];
    	}//256
    	for(int i=0; i<256*cnt; i++) {
    		S[++opt]=S[i];
    	}//512
    	for(int i=0; i<512*cnt; i++) {
    		S[++opt]=S[i];
    	}//1024
    	for(int i=L-1; i<R; i++) {
    		ans+=(int)S[i];
    	}
    	cout<<ans;
    	/*	for(int i=2*opt;i>=opt+1;i--){
    			S[i]=
    		}*/
    	/*	for(int i=1; i<=cnt; i++)
    			cout<<(int)S[i]<<"
    ";*/
    	return 0;
    }
    

    不过考试的时候,看见坐在我旁边的cgp Dalao一直在咳咳(面露微笑)。阔怕阔怕~隐隐约约还听到他忽然叫了一句:我想到优化了!!(果然,我太菜了)

    AC代码:

    #include<iostream>
    #include<stack>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    #define N 100011
    
    #define LL long long int
    
    stack<int>S;
    
    int a[N];
    
    int cnt=0;
    
    LL x,y,l,r,k;
    
    LL ans=0,sum=0;
    
    int main(void) {
    	freopen("circulate.in","r",stdin);
    	freopen("circulate.out","w",stdout);
    	cin>>x>>y>>l>>r;
    	while(x<=y) {
    		k=x;
    		while(k!=0) {
    			S.push(k%10);
    			k=k/10;
    		}
    		while(!S.empty()) {
    			cnt++;
    			a[cnt]=S.top();
    			S.pop();
    		}
    		x++;
    	}
    	int flag=0;
    	sum=1;
    	for(int i=1; i<=cnt+1; i++) {
    		if(i==cnt+1) i=1;
    		if(sum==l) {
    			flag=1;
    		}
    		if(flag)
    			ans+=a[i];
    		sum++;
    		if(sum==r+1) break;
    	}
    	cout<<ans;
    	return 0;
    }
    

    T3合并游戏

    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

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define N 1111
    
    int n;
    
    int a[N];
    
    int ans=0;
    
    int opt=0;
    
    int main(void) {
    	freopen("merge.in","r",stdin);	
    	freopen("merge.out","w",stdout);	
    	priority_queue<int> Q;//大头堆
    	cin>>n;
    	for(int i=1; i<=n; i++) {
    		cin>>a[i];
    		Q.push(a[i]);
    	}
    	if(n<=3) {
    		for(int i=1; i<=n; i++) ans+=a[i];
    		cout<<ans;
    		return 0;
    	} else {
    		ans+=Q.top();
    		Q.pop();//1
    		ans+=Q.top();
    		Q.pop();//2
    		ans+=Q.top();
    		Q.pop();//3
    		Q.push(ans);
    		int uxv=0;
    		while(Q.size()>3) {
    			for(int i=1; i<=3; i++) {
    				uxv+=Q.top();
    				Q.pop();
    			}
    			ans+=uxv;
    			Q.push(uxv);
    			uxv=0;
    		}
    		uxv=0;
    		if(Q.size()<=3) {
    			while(!Q.empty()) {
    				uxv+=Q.top();
    				Q.pop();
    			}
    			ans+=uxv;
    		}
    		cout<<ans;
    		return 0;
    	}
    }
    

    综合而言:这次考试我真的**了。

  • 相关阅读:
    2021 3 11 结队博客
    第一周 2021.03.07
    2021 3 5 知识点总结
    2021 3 3 每日总结
    2021 3 2 新学期的第一篇博客
    十天冲刺09
    二阶段之四
    安卓开发之实现手机验证码登录
    安卓布局(三)
    安卓布局(二)
  • 原文地址:https://www.cnblogs.com/morbidity/p/10841169.html
Copyright © 2020-2023  润新知