常州大学新生寒假训练Round 4题解
比赛地址:https://vjudge.net/contest/207674
迷路的白学姐
- 、”蜜蜂只能爬向右侧相邻的蜂房”准确来说,包含三个方向:正右方,右下方,右上方。
- 到 1 只有一条路(本身嘛),到 2 有一条路线(1 -> 2),到 3 有两条路线(1 ->3 或者 2 -> 3),到 4 有 3 条路线(到 2 的 1 条加上到 3 的 2 条),到 5 有 5 条路线(到 3 的 2 条加上到 4 的 3 条)……
- 以此类推,从原点到达各个蜂房的路线数分别为:
蜂房号 1 2 3 4 5 6 7 8 9 ……
路线数 1 1 2 3 5 8 13 21 34 ……
- 然后就可以发现,这就是一个斐波那契数列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include<bits/stdc++.h> using namespace std; int main() { int n; long long c[100]; c[0]=1; c[1]=1; c[2]=2; int a,b,j; while(cin>>n) { for(int i=0;i<n;i++) { cin>>a>>b; for(j=2;j<=b-a;j++) { c[j]=c[j-1]+c[j-2]; } cout<<c[j-1]<<endl; } } return 0; }
|
热爱公平的白学姐
既然要保持大家公平,就只能找出序列中的最大值,并将大家补全成最大值即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include<bits/stdc++.h> using namespace std; int a[100+10]; int main() { int n,maxi=-1,ans=0; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i]); maxi=max(maxi,a[i]); } for(int i=0;i<n;i++) { ans+=maxi-a[i]; } printf("%d\n",ans); return 0; }
|
白学姐的填字游戏
只有一种情况时就是在相邻两个连续1子串中只能含有一个0,只有一个连续1子串则整个串中不能含有0
我们就要计算总共1的个数,然后看看剩下的0的个数是不是刚好能隔开每一个1串
只要满足a1+a2+…+an=x-n+1即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <bits/stdc++.h> using namespace std; int main() { int n,x,tmp,sum=0; scanf("%d%d",&n,&x); for(int i=1;i<=n;i++){ cin>>tmp; sum+=tmp; } sum+=(n-1); if(sum==x) printf("YES\n"); else printf("NO\n"); return 0; }
|
打工的白学姐
首先考虑不进行抛售时能卖出多少,就是存货量和购买量中的较小值,如果抛售就会增加存货量*2和购买量的最小值减之前那个值的销售数量,那么我们统计出如果进行抛售,每天的销售数量增量,取最大的f天,再加上每一天不抛售的销售量就是答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <cstdio> #include <algorithm> using namespace std; long long k[100001],l[100001]; long long add[100001]; int main() { long long n,f,ans; scanf("%I64d%I64d",&n,&f); for(long long i=0;i<n;i++) { scanf("%I64d%I64d",&k[i],&l[i]); add[i]=min(2*k[i],l[i])-min(k[i],l[i]); } sort(add,add+n);
reverse(add,add+n); ans=0; for(long long i=0;i<n;i++) ans+=min(k[i],l[i]); for(long long i=0;i<f;i++) ans+=add[i]; printf("%I64d\n",ans); return 0; }
|
白学姐安排座位
题意
贪心做法,首先将每四个同一队伍的人安排到中间位置四人座(3,4,5,6),如果四人座有空余则将每个四人座分解为一个双人座和一个单人座。然后再将每两个同一队伍的人安排到所有的双人座,若双人座有空余则分解为一个单人座,最后看单人座能否将所有安排满,若可以,输出YES,否则输出NO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <bits/stdc++.h> using namespace std;
int main() { int n,k,x; cin >> n >> k; int sum2 = n*2,sum4 = n; int x1 = 0,x2 = 0,x3 = 0,x4 = 0; for(int i=1;i<=k;i++) { cin >> x; x4 += x/4; if(x%4==3) x3 ++; if(x%4==2) x2 ++; if(x%4==1) x1 ++; } while(sum4>0 && x4>0) {sum4--;x4--;} while(sum4>0 && x3>0) {sum4--;x3--;} while(sum4>0 && x2>0) {sum4--;x2--;x1--;} while(sum4>0 && x1>0) {sum4--;x1--;sum2++;} while(sum2>1 && x4>0) {sum2-=2;x4--;} while(sum2>1 && x3>0) {sum2-=2;x3--;} while(sum2>0 && x2>0) {sum2--;x2--;} while(sum2>0 && x1>0) {sum2--;x1--;} if(x2*2+x3*3+x4*4+x1<=0) cout << "YES" << endl; else if(x1<=0 && x2<=0 && x3<=0 && x4<=0) cout << "YES" << endl; else cout << "NO" << endl; return 0; }
|
另一种写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <bits/stdc++.h> using namespace std;
int n, k; int rest[5], cnt[5];
inline void init() { scanf("%d%d", &n, &k); rest[2] = n << 1, rest[4] = n; for(int i = 1, x; i <= k; i++) { scanf("%d", &x); while(x > 2) { if(rest[4]) rest[4]--, x -= 4; else if(rest[2]) rest[2]--, x -= 2; else { puts("NO"); exit(0); } } if(x) cnt[x]++; } }
inline void solve() { while(cnt[2]--) { if(rest[4]) rest[4]--, rest[1]++; else if(rest[2]) rest[2]--; else cnt[1] += 2; } puts((rest[4] * 2 + rest[2] + rest[1] >= cnt[1]) ? ("YES") : ("NO")); }
int main() { init(); solve(); return 0; }
|