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]<<"\n";*/
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;
}
}
综合而言:这次考试我真的**了。