19.05.09 解題報告
預計得分:100+50+100=250
實際得分:5+50+0=55
發下試題,看了一遍三個題:
T1 題、裸的背包
T2 我可以模擬()
T3 **題、貪心、優先隊列
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;
}
}
綜合而言:這次考試我真的**了。
19.05.09 解題報告