2019 8月 纪中第一天(c组)
窗外是倾盆大雨,昏暗一片。想起今早被雨淋湿的一身便很无奈。食堂不咋滴,机房管理太严,整个人都不好了。下面是今天的题目。
题目(1)
Wexley最近发现了一个古老的屏幕游戏。游戏的屏幕被划分成n列。在屏幕的底端,有一个宽为m列的篮子(m<n)。在游戏过程中,Wexley能左右移动这个篮子, Wexley的操作很犀利,移动是瞬间完成的,但是篮子必须始终都在屏幕中。 苹果从屏幕的顶端落下,每个苹果从n列中的某一列顶端掉落,垂直掉落到屏幕的底端。每个苹果总是在上一个苹果掉落到底端的时候开始掉落。Wexley想要通过移动篮子来接住所有的苹果。起先,篮子在屏幕的最左端。
求出Wexley要接住所有的苹果所需移动的最短距离。
输入
第二行,一个整数k,表示掉落的苹果总数
接下来k行,每行一个整数Ai,表示每个苹果掉落的位置
输出
样例输入
Sample Input1:
5 1
3
1
5
3
Sample Input2:
5 2
3
1
5
3
样例输出
Sample Output1:
6
Sample Output2:
4
思路
用left,right确定左右区间。大时用右靠近,小时用左靠近。ans记录走的步数
代码
#include<algorithm> #include<cmath> #include<cstdio> #include<iostream> #include<cstring> using namespace std; int main() { freopen("apple.in","r",stdin); freopen("apple.out","w",stdout); int n,m,k,a[21],ans=0,right,left; scanf("%d%d",&n,&m); scanf("%d",&k); for(int i=1;i<=k;i++) scanf("%d",&a[i]); left=1; right=1+m-1; for(int i=1;i<=k;i++) { if(a[i]>right) { ans=ans+a[i]-right; right=a[i]; left=a[i]-m+1; } else if(a[i]<left) { ans=ans+left-a[i]; left=a[i]; right=a[i]+m-1; } } printf("%d",ans); return 0; }
题目(2)
输入
接下来n行,每行3个整数li,wi,hi,表示积木的长宽高
输出
样例输入
1
10 20 30
Sample Input2:
2
6 8 10
5 5 5
Sample Input3:
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
样例输出
Sample Output1:
40
Sample Output2:
21
Sample Output3:
342
思路
先把一切可能性都列出来。用快排把长从小到大排一遍。num记录它最高能有多高。a[i].num=a[i].h(积木高度)+a[j].num(比它大的上一块积木)。
代码
#include<algorithm> #include<cmath> #include<cstdio> #include<iostream> #include<cstring> using namespace std; struct Node { int h; int l; int w; int num; }; Node a[9001]; bool cmp(Node x,Node y) { return x.l<y.l; } int main() { freopen("brick.in","r",stdin); freopen("brick.out","w",stdout); int n,k=1,ans=0,sum=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d%d",&a[i].l,&a[i].w,&a[i].h); if(a[i].l<a[i].w) swap(a[i].l,a[i].w); } for(int i=n+1;i<=2*n;i++) { a[i].l=a[k].w; a[i].w=a[k].h; a[i].h=a[k].l; if(a[i].l<a[i].w) swap(a[i].l,a[i].w); k++; } k=1; for(int i=2*n+1;i<=3*n;i++) { a[i].l=a[k].h; a[i].h=a[k].w; a[i].w=a[k].l; if(a[i].l<a[i].w) swap(a[i].l,a[i].w); k++; } sort(a+1,a+3*n+1,cmp); for(int i=1;i<=3*n;i++) a[i].num=a[i].h; for(int i=3*n;i>=1;i--) for(int j=i+1;j<=3*n;j++) if(a[i].w<a[j].w&&a[i].num<a[i].h+a[j].num&&a[i].l!=a[j].l) a[i].num=a[i].h+a[j].num; for(int i=1;i<=3*n;i++) ans=max(ans,a[i].num); printf("%d",ans); return 0; }
接下来的题目没有题解。接下来的时间可能会补上!!!
题目(3)
Treeland是一个有n个城市组成的国家,其中一些城市之间有单向边连通。在这个国家中一共有n-1条路。我们知道,如果我们不考虑路的方向,那么我可以从任意城市到达任意城市。
最近,Treeland的总理Candy为了发展经济,想要从这n个城市中选择一个作为Treeland的首都,首都必须要能到达其他任意城市,这使得有些道路必须反向,付出的代价即需要反向的道路条数。
Candy想要选择一个城市作为首都,使得付出的代价最小。可能有多个城市满足条件,按编号从小到大输出。
输入
接下来n-1行,每行两个整数x、y,表示城市x到城市y之间有一条单向路径
输出
第二行若干个整数,中间用空格隔开,表示满足条件的城市编号。行末没有多余的空格。
样例输入
Sample Input1:
3
2 1
2 3
Sample Input2:
4
1 4
2 4
3 4
样例输出
Sample Output1:
0
2
Sample Output2:
2
1 2 3
题目
马上假期就要到了,THU的神犇Leopard假期里都不忘学霸,现在有好多门功课,每门功课都耗费他1单位时间来学习。
他的假期从0时刻开始,有1000000000个单位时间(囧rz)。在任意时刻,他都可以任意一门功课(编号1~n)来学习。
因为他在每个单位时间只能学习一门功课,而每门功课又都有一个截止日期,所以他很难完成所有n门功课。
对于第i门功课,有一个截止时间Di,若他能学完这门功课,他能够获得知识Pi。
在给定的功课和截止时间下,Leopard能够获得的知识最多为多少呢?
接下来n行,每行两个整数,Di和Pi
输出
样例输入
3
2 10
1 5
1 7
样例输出
17
【样例说明】
第一个单位时间学习第3个功课(1,7),然后在第二个单位时间学习第1个功课(2,10)