usaco 2010年3月银组题解
usaco银组解题报告
一.石子游戏
如果把‘O’当作0,‘X’当做1,则N个洞的每一种状态都可以看做是一个N位二进制数。于是,这个问题就变成了求环绕的N位格雷码。幸运的是,这个结构很容易就能够用一个简单的递归式计算出来。
假设我们有一组K位格雷码序列,第一个为K个0. 我们可以复制这个格雷码序列,并将其倒序,然后将它加在原来的格雷码序列之后。现在,在原来的格雷码序列中的每个数之前都加上数字0,而在复制的序列中每个数的前面都加上1。然后,结果序列就将称为一个有效的k+1位的格雷码。这儿是一个K=2的例子。
1. 原来的格雷码序列,K=2
00
01
11
10
2. 复制并倒序,然后加在原来序列的后面。
00
01
11
10
10
11
01
00
3. 在前面加一个数字。
000
001
011
010
110
111
101
100
如果我们使用这种构造方法,得到的以100……00结尾的序列正是我们想要的。这种算法的时间复杂度是O(2^N),因为每一个数都是从其他的地方精确的复制过来,每一次复制都花费一个常数时间。
下面给出这个问题的一个简单的以位运算实现的源程序。
01 /*
02 LANG: C++
03 Coded by Jaehyun park
04 */
05
06 #include<cstdio>
07 int n;
08 int a[1<<15+1];
09 int main() {
10 int i, j, k;
11 FILE *ifp=fopen("rocks.in", "r"), *ofp=fopen("rocks.out", "w");
12 fscanf(ifp, "%d", &n);
13 for(k=0;k<n;k++)
14 for(i=0;i<(1<<k);i++)
15 a[(1<<(k+1))-i-1]=a[i]|(1<<k);
16 for(i=0;i<=(1<<n);i++) {
17 for(j=0;j<n;j++)
18 fprintf(ofp, "%c", a[i]&(1<<j)?'X':'O');
19 fprintf(ofp, "\n");
20 }
21 return 0;
22 }
2.考试
考察下面给出的三种情况:
1. 设t_max为所有t_i的最大值。不管其他的t_i的值为多少,FJ能够保证N-t_max个正确答案,他只需全部选择false。
2. 设t_min为所有t_i的最小值。不管其他的t_i值为多少,FJ能够保证t_min个正确答案,他只需全部选择true。
3. 将所有按从大到小排序,t_i设t_x 和 t_y是相邻的两个t_i(t_x>t_y),FJ可以保证(t_x-t_y)/2个正确答案,他只需选择N-[(t_x+t_y)/2]个正确答案,其余全部选择false。
这是一个例子:
|----->120
|--------->200
|---------------->340
|-------------------->420
|--------------------------------->680
|--------------------------------------->800
0 |----+----+----+----+----+----+----+----+----+----| 1000
总共有1000个题,答案为true的题分别为120,200,340,420,680,800,1000.我们将它们排序后,再来查看相邻的数据。
Case1:1000 - 800 = 200个正确答案可以保证,只需全部选false。
Case2:120个正确答案可以保证,只需要全部选true。
Case3:对于相邻的两个值420和680,(680 - 420) / 2 = 130个正确答案可以保证,只需要选择1000 - [(680 + 420) / 2] = 450个true。因为,如果有420个为true的答案,可以保证1000-420-450=130个false选择正确,而如果有680个true,也能保证有680+450-1000个true被选中。
现在,我们可以通过排序然后检查相邻值的差来解决这个问题。比较三种情形,找出其中最大的就行了。从上面这个例子,我们可以得到答案是200.
下面给出源代码:
01 #include <iostream>
02 #include <algorithm>
03 #include <memory.h>
04 using namespace std;
05
06 int a[10100];
07
08 int main () {
09 FILE* in = fopen ("teststr.in", "r");
10 FILE* out = fopen ("teststr.out", "w");
11
12 int N, K;
13 fscanf (in, "%d %d", &N, &K);
14
15 for (int i = 0; i < K; i++) {
16 int v; fscanf (in, "%d", &v);
17 a[i] = N - v;
18 }
19 sort (a, a + K);
20
21 int best = a[0];
22 for (int i = 0; i < K-1; i++)
23 best = max (best, (a[i+1] - a[i]) / 2);
24 best = max (best, N - a[K-1]);
25 fprintf (out, "%d\n", best);
26
27 fclose (in);
28 fclose (out);
29 }
三.赛车
在这道题中,关键就是下面这个结论:
对于任意的i和j,如果
F F_i F_j
--- < ----- < -----
M M_i M_j
则有
F F + F_i F + F_j
--- < --------- < ---------
M M + M_i M + M_j
换句话说,配件的加速性能越好,那么它加到汽车上,给车子带来的加速性能也越好。于是,解决方案就是按配件的加速性能(F_i/M_i)从高到低一个个加到汽车上,直到汽车的加速性能不能再提升为止。因为配件的数目N很大,所以对于配件按加速性能的排序要控制在O(N log N)的时间复杂度以内。否则,如果是O(N^2)的话,可能会超时。
例如,排序后的配件如下:
i F_i M_i F_i/M_i F/M
4 200 8 25.0 15.7407
3 120 5 24.0 16.1062
2 150 9 16.7 16.1475 <-- stop adding parts here
1 250 25 10.0 15.1020
上面的F/M列显示了最后的加速性能及对应的配件。我们一次增加配件4,3,2,再增加了配件2以后,再增加配件1已经不能提高车子的加速性能了,相反还会下降到15.1020.
下面给出源程序:
01 #include <fstream>
02 #include <algorithm>
03 #define MAX 10000
04 using namespace std;
05
06 int M,N;
07 double F;
08 bool mark[MAX+1];
09
10 struct Boost {
11 int id, m;
12 double f;
13 bool operator<(const Boost& y) const
14 { return f*y.m > y.f*m; }
15 } p[MAX];
16
17 int main () {
18 ifstream fin("sboost.in");
19 fin >> F >> M >> N;
20 for (int i=0; i<N; p[i].id=++i)
21 fin >> p[i].f >> p[i].m;
22 fin.close();
23
24 bool add=false;
25 // sort accelerations of the boosters
26 sort(p,p+N);
27 // take the booster if new acceleration is greater than current
28 for (int i=0; i<N; i++)
29 if (F/M < (F+p[i].f)/(M+p[i].m))
30 F+=p[i].f, M+=p[i].m, mark[p[i].id]=true, add=true;
31
32 ofstream fout("sboost.out");
33 if (!add)
34 fout << "NONE\n";
35 else
36 for (int i=1; i<=N; i++)
37 if (mark[i]) fout << i << "\n";
38 fout.close();
39 }
usaco 2010年3月银组题解的更多相关文章
- USACO[19-20]Dec银组题解
1,MooBuzz 这题其实是道数学题. 我们先找找符合要求的数:1,2,4,7,8,11,13,14…… 我们发现再往后找都是这8个数中的一个加15k如:16……19……29…… 找规律发现k=n/ ...
- BZOJ USACO 银组 水题集锦
最近刷银组刷得好欢快,好像都是水题,在这里吧他们都记录一下吧(都是水题大家一定是道道都虐的把= =)几道比较神奇的题到时再列出来单独讲一下吧= =(其实我会说是BZOJ蹦了无聊再来写的么 = =) [ ...
- csu-2018年11月月赛Round2-div1题解
csu-2018年11月月赛Round2-div1题解 A(2191):Wells的积木游戏 Description Wells有一堆N个积木,标号1~N,每个标号只出现一次 由于Wells是手残党, ...
- NC24724 [USACO 2010 Feb S]Chocolate Eating
NC24724 [USACO 2010 Feb S]Chocolate Eating 题目 题目描述 Bessie has received \(N (1 <= N <= 50,000)\ ...
- NOIP2008普及组题解
NOIP2008普及组题解 从我在其他站的博客直接搬过来的 posted @ 2016-04-16 01:11 然后我又搬回博客园了233333 posted @ 2016-06-05 19:19 T ...
- noip2010提高组题解
NOIP2010提高组题解 T1:机器翻译 题目大意:顺序输入n个数,有一个队列容量为m,遇到未出现元素入队,求入队次数. AC做法:直接开1000的队列模拟过程. T2:乌龟棋 题目大意:有长度为n ...
- VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程 转载
VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程 转载 #include <stdio.h>#include &l ...
- NOIP 2014 提高组 题解
NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法 ...
- NOIP 2001 提高组 题解
NOIP 2001 提高组 题解 No 1. 一元三次方程求解 https://vijos.org/p/1116 看见有人认真推导了求解公式,然后猥琐暴力过的同学们在一边偷笑~~~ 数据小 暴力枚举即 ...
随机推荐
- UVa 1346 - Songs
题目大意:n张唱片,每张都有长度和频率,要求题目中公式值最小.求一个排序,输出该排序下第m张CD的id. 思路:贪心,长度越长放越后面,频率越低放越后面,所以按len/p去排序即可. #include ...
- JavaWeb学习记录(二十六)——在线人数统计HttpSessionListener监听实现
一.session销毁控制层代码 public class InvalidateSession extends HttpServlet { public void doGet(HttpServletR ...
- Codeforces Round #155 (Div. 2)
A. Cards with Numbers 模拟. B. Jury Size 相当于统计单天最大需要人数,会发生变化的点在区间两端,枚举计算即可. C. Anagram 从小到大枚举字母: 若当前字母 ...
- [luogu P2647] 最大收益(贪心+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品. ...
- springMvc源码学习之:spirngMvc的拦截器使用
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- Linux-同步异步非阻塞阻塞的解析
一.理解同步.异步.阻塞.非阻塞 出场人物:老张,水壶两把(普通水壶,简称水壶:会响的水壶,简称响水壶). 1 老张把水壶放到火上,立等水开.(同步阻塞) 老张觉得自己有点傻. 2 老张把水壶放到火上 ...
- JS之变量的运算
js变量的特点: 1.区分大小写,这是与html及css最大的不同: 2.弱变量.通过var进行定义,无明确的数据类型. 第一部分 字符型 对于字符型的数据,常用的操作为字符的转换.字符的操作 1.字 ...
- threading模块和queue模块实现程序并发功能和消息队列
简介: 通过三个例子熟悉一下python threading模块和queue模块实现程序并发功能和消息队列. 说明:以下实验基于python2.6 基本概念 什么是进程? 拥有独立的地址空间,内存,数 ...
- 一个不错的vim配置
set nocp set backspace=indent,eol,start set number set autoindent set nocompatible set bs=indent,eol ...
- 从代码看 asp.net 处理过程
从这里开始 先是一个 对Com接口的导入. /// <internalonly/> /// <devdoc> /// </devdoc> [C ...