A
题意:多个教室经过走廊搬桌子,不能共用已被占用的走廊(不相交可以同时搬运),每次需要十分钟,问最少需要的时间。
思路:每次搬运都会覆盖一段走廊,会覆盖这段的点,找出所有点中覆盖次数最多的即是需要搬运的最大次数。
B
题意:O(-1)
思路:O(-1)。
C
题意:有n头牛在一条线上,每头牛都会嚎叫,为了让所有牛都听见,嚎叫的声音等于离它最远牛的距离,问所有牛嚎叫的声音分贝是多少。
思路:对所有牛按位置排序,分贝划过两头牛之间距离的次数之和便是答案,遍历即可。
D
题意:有n个人,每个人都有m张纸牌,所有的纸牌都在1~n*m之间并且不重复,每轮每个人拿出一张纸牌比较大小,最大的赢得这轮。给出你的m张纸牌大小,问你最小能赢多少轮。
思路:你从最小开始出,对方先出一张比你大的,其他人从最小开始出,依次继续。当你再次出牌的时候找不到对手点数有比你大的,那么你后面都是赢。
E
题意:给你n种品牌交流机器,每种类型交流机器又有m种分支产品,现在让你从n种品牌中各选择一种,要求B/P最大,B为这选择的n种中b最小的,P则为选择的n种的价值和。
思路:枚举所有出现的B,对每种产品的p进行从小到大排序,每次都选择这种产品中第一个大于B的。选取所有枚举情况的最优解即可。
F
题意:O(-1).
思路:不对局部而对全程分析,你跟到最后一起到达终点的必是在你后出发而又最快到达终点的。
G/H
题意:O(-1)
思路:两题类似。先对罚时从大到小排序,对于每门功课,从最后期限开始往前找(保证最优解),找到空位即可。
I
题意:给出海面上n个岛屿的坐标,给出你雷达扫描半径,问你最少要安装多少个雷达才可监控到所有的海上岛屿。
思路:对每个岛屿分析可知,每个岛屿可被地面上一段[l,r]内的雷达扫射到,只要雷达安装到这段区域内便可监控到该岛屿。处理出所有的这些区间段,排序后从左到右扫一遍,覆盖区域选最左边的右端点值rbd,在rbd左边的相交区域选一个雷达即可。
J
题意:O(-1)
思路:排序之后从左往右铺即可,要注意的一点是当木板很长很长的一种情况。
K
题意:O(-1).
思路:黑书上的一道例题。因为钓鱼只能从左往右走,枚举所有情况:即只走到第i个(i输出1~n)。然后对于枚举的每种情况,选择鱼最多的池塘去钓鱼,这时候你可以想象成你能飞来飞去。
L
题意:有一颗n个节点n-1条边的树,每个节点有一个C[i]值,每到达一个节点time加1,到达这个节点的处罚是time*C[i],并且只有当父亲节点走完了才能走孩子节点。
思路: 开始对C值进行排序,每次都找未标记的C值最大的节点,从该节点往前走到根节点都标记一下,后来证明这样是错的。
因为每个节点受限制于父亲节点,正确的处理方法是利用fact[i]/num[i]进行贪心操作,fact[i]表示该节点集合的C值总和,num表示该集合的节点数。每次选取fact[i]/num[i]最大的,并将它归并与父亲集合,父亲num值加1。

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 typedef long long lld; 8 const int maxn=1024; 9 int pre[maxn], next[maxn][maxn], ind[maxn], visit[maxn], fact[maxn], num[maxn]; 10 int n, rt; 11 12 int find() 13 { 14 double maxx=0, pos=-1; 15 for(int i=1; i<=n; i++) 16 if(!visit[i]&&i!=rt&&1.0*fact[i]/num[i]>maxx) 17 { 18 maxx=1.0*fact[i]/num[i]; 19 pos=i; 20 } 21 return pos; 22 } 23 24 void Union(int x, int y) 25 { 26 for(int i=1; i<=ind[x]; i++) 27 { 28 pre[ next[x][i] ]=y; 29 next[y][++ind[y]]=next[x][i]; 30 } 31 fact[y]+=fact[x]; 32 num[y]+=num[x]; 33 } 34 35 void Solve() 36 { 37 int ans=0; 38 for(int i=1; i<n; i++) 39 { 40 int id=find(); 41 if(id==-1) break; 42 visit[id]=1; 43 ans+=fact[id]*num[ pre[id] ]; 44 Union(id,pre[id]); 45 } 46 cout << ans+fact[rt] <<endl; 47 } 48 49 int main() 50 { 51 while(cin >> n >> rt, n+rt) 52 { 53 memset(visit,0,sizeof(visit)); 54 memset(next,0,sizeof(next)); 55 memset(ind,0,sizeof(ind)); 56 for(int i=1; i<=n; i++) 57 { 58 scanf("%d",fact+i); 59 num[i]=1; 60 } 61 for(int i=1; i<=n-1; i++) 62 { 63 int u, v; 64 scanf("%d%d",&u,&v); 65 pre[v]=u; 66 next[u][++ind[u]]=v; 67 } 68 Solve(); 69 } 70 }
M
题意:O(-1)
思路:从大到小,三个一组,所有组里面最小的之和即使答案。