Google Code Jam Round 1A 2015 Problem B. Haircut 二分
- Problem
- You are waiting in a long line to get a haircut at a trendy barber shop.
The shop has B barbers on duty, and they are numbered 1 through B.
It always takes the kth barber exactly Mk minutes to cut a customer's hair,
and a barber can only cut one customer's hair at a time. Once a barber
finishes cutting hair, he is immediately free to help another customer.- While the shop is open, the customer at the head of the queue always goes
to the lowest-numbered barber who is available. When no barber is available,
that customer waits until at least one becomes available.- You are the Nth person in line, and the shop has just opened. Which barber
will cut your hair?- Input
- The first line of the input gives the number of test cases, T. T test cases
follow; each consists of two lines. The first contains two space-separated
integers B and N -- the number of barbers and your place in line.
The customer at the head of the line is number 1, the next one is number 2,
and so on. The second line contains M1, M2, ..., MB.- Output
- For each test case, output one line containing "Case #x: y",
where x is the test case number (starting from 1) and y is the number of the barber who will cut your hair.- Limits
- 1 ≤ T ≤ 100.
- 1 ≤ N ≤ 109.
- Small dataset
- 1 ≤ B ≤ 5.
- 1 ≤ Mk ≤ 25.
- Large dataset
- 1 ≤ B ≤ 1000.
- 1 ≤ Mk ≤ 100000.
- Sample
- Input
- Output
- 3
- 2 4
- 10 5
- 3 12
- 7 7 7
- 3 8
- 4 2 1
- Case #1: 1
- Case #2: 3
- Case #3: 1
- In Case #1, you are the fourth person in line, and barbers 1 and 2 take 10 and 5 minutes,
respectively, to cut hair. When the shop opens, the first customer immediately has the
choice of barbers 1 and 2, and she will choose the lowest-numbered barber, 1. The second
customer will immediately be served by barber 2. The third customer will wait since there
are no more free barbers. After 5 minutes, barber 2 will finish cutting the second
customer's hair, and will serve the third customer. After 10 minutes, both barbers 1 and
2 will finish; you are next in line, and you will have the choice of barbers 1 and 2, and will choose 1.
题目很简短,也很好理解。
如果用最朴素的方法,不管是暴力还是用 STL 里的 SET ,都需要从 1 遍历到 N (10^9) 那么肯定是不行的
我想到了既然人数那么多说不定有规律可循,过了小数据, TLE 了大数据... 【姿势不对啊
- //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
- #include <stdio.h>
- #include <iostream>
- #include <fstream>
- #include <cstring>
- #include <cmath>
- #include <stack>
- #include <string>
- #include <map>
- #include <set>
- #include <list>
- #include <queue>
- #include <vector>
- #include <algorithm>
- #define Max(a,b) (((a) > (b)) ? (a) : (b))
- #define Min(a,b) (((a) < (b)) ? (a) : (b))
- #define Abs(x) (((x) > 0) ? (x) : (-(x)))
- #define MOD 1000000007
- #define pi acos(-1.0)
- using namespace std;
- typedef long long ll ;
- typedef unsigned long long ull ;
- typedef unsigned int uint ;
- typedef unsigned char uchar ;
- template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
- template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}
- const double eps = 1e- ;
- const int M = * ;
- const ll P = 10000000097ll ;
- const int MAXN = ;
- const int INF = 0x3f3f3f3f ;
- int B, N;
- int a[], cur[];
- int ans[];
- int main(){
- std::ios::sync_with_stdio(false);
- int i, j, t, k, u, v, numCase = ;
- ofstream fout ("B-large-practice.out");
- ifstream fin ("B-large-practice.in");
- fin >> t;
- int T = t;
- for (T = ; T <= t; ++T) {
- cout << T << endl;
- fin >> B >> N;
- for (i = ; i <= B; ++i) {
- fin >> a[i];
- }
- memset (cur, , sizeof (cur));
- int flag = ;
- int sum = ;
- for (i = ; i < N; ++i) {
- cur[flag] += a[flag];
- ans[sum++] = flag;
- int MIN = INF;
- for (j = ; j <= B; ++j) {
- if (cur[j] < MIN) {
- MIN = cur[j];
- flag = j;
- }
- }
- for (j = ; j < B; ++j) {
- if (cur[j] ^ cur[j + ]) {
- break;
- }
- }
- if (j == B) {
- break;
- }
- }
- if (i == N) {
- flag = ;
- for (i = ; i <= B; ++i) {
- if (cur[i] < cur[flag]) {
- flag = i;
- }
- }
- } else {
- if (N % sum == ) {
- flag = ans[sum - ];
- } else {
- flag = ans[N % sum - ];
- }
- }
- fout << "Case #" << ++numCase << ": " << flag << endl;
- }
- return ;
- }
Naive Solution
正确解法如下:
对于已知的B 位理发师,我们可以知道,在第 t 时间单位的时候,可以有 number 个数的人已经理发
因为我们要求的是第 n 个人是哪个理发师给他理发,那么从这里开始想下去
可以考虑对时间进行二分
找到第 t 时间单位,在那个时间点保证第 n 个人理发完毕
好,那么我们有个这个时间 t
接下来就是找,是第几个理发师理的头发
这时候需要一个新的变量 tt = t - 1, 表示在前一秒,我们可以在这里进行模拟
如果 tt % a[i] == 0, 意思就是如果在 tt 的时间单位时第 i 个理发师可以理发,那么作累加
直到刚刚好某个理发师碰到 第 n 个人的时候 break 输出答案即可。
Source Code:
- //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
- #include <stdio.h>
- #include <iostream>
- #include <fstream>
- #include <cstring>
- #include <cmath>
- #include <stack>
- #include <string>
- #include <map>
- #include <set>
- #include <list>
- #include <queue>
- #include <vector>
- #include <algorithm>
- #define Max(a,b) (((a) > (b)) ? (a) : (b))
- #define Min(a,b) (((a) < (b)) ? (a) : (b))
- #define Abs(x) (((x) > 0) ? (x) : (-(x)))
- #define MOD 1000000007
- #define pi acos(-1.0)
- using namespace std;
- typedef long long ll ;
- typedef unsigned long long ull ;
- typedef unsigned int uint ;
- typedef unsigned char uchar ;
- template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
- template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}
- const double eps = 1e- ;
- const int M = ;
- const ll P = 10000000097ll ;
- const int INF = 0x3f3f3f3f ;
- const int MAX_N = ;
- const int MAXSIZE = ;
- const int MK = ;
- const int N = ;
- int b;
- ll n, a[N];
- ll cal(ll n) { //求出[0,n - 1] 时间内所有理发师理发的总人数
- ll ret = ;
- for (int i = ; i < b; ++i) {
- ret += (n - + a[i]) / a[i]; //n - 1 表示(n - 1) 的时间, 表达式表示第i个理发师在前(n-1)时间内理发的人数
- }
- return ret;
- }
- int main() {
- ofstream fout ("B-large-practice.out");
- ifstream fin ("B-large-practice.in");
- int T, i, j, k;
- fin >> T;
- while (T--) {
- fin >> b >> n;
- for (i = ; i < b; ++i) {
- fin >> a[i];
- }
- ll l = , r = n * MK;
- while (l < r) {
- ll mid = l + r >> ;
- if (cal(mid) < n) {
- l = mid + ;
- } else {
- r = mid;
- }
- }
- int last = cal(l - ), ans = ;
- for (i = ; i < b; ++i) {
- if ((l - ) % a[i] == ) {
- ++last;
- if (last == n) {
- ans = i + ;
- break;
- }
- }
- }
- static int numCase = ;
- fout << "Case #" << ++numCase << ": " << ans << endl;
- }
- return ;
- }
Google Code Jam Round 1A 2015 Problem B. Haircut 二分的更多相关文章
- Google Code Jam Round 1A 2015 解题报告
题目链接:https://code.google.com/codejam/contest/4224486/ Problem A. Mushroom Monster 这题题意就是,有N个时间点,每个时间 ...
- Google Code Jam Round 1C 2015 Problem A. Brattleship
Problem You're about to play a simplified "battleship" game with your little brother. The ...
- [Google Code Jam (Round 1A 2008) ] A. Minimum Scalar Product
Problem A. Minimum Scalar Product This contest is open for practice. You can try every problem as ...
- 【二分答案】Google Code Jam Round 1A 2018
题意:有R个机器人,去买B件商品,有C个收银员,每个收银员有能处理的商品数量上限mi,处理单件商品所需的时间si,以及最后的装袋时间pi. 每个收银员最多只能对应一个机器人,每个机器人也最多只能对应一 ...
- 【贪心】Google Code Jam Round 1A 2018 Waffle Choppers
题意:给你一个矩阵,有些点是黑的,让你横切h刀,纵切v刀,问你是否能让切出的所有子矩阵的黑点数量相等. 设黑点总数为sum,sum必须能整除(h+1),进而sum/(h+1)必须能整除(v+1). 先 ...
- Google Code Jam 2014 资格赛:Problem B. Cookie Clicker Alpha
Introduction Cookie Clicker is a Javascript game by Orteil, where players click on a picture of a gi ...
- Google Code Jam 2014 资格赛:Problem D. Deceitful War
This problem is the hardest problem to understand in this round. If you are new to Code Jam, you sho ...
- [刷题]Google Code Jam 2017 - Round1 C Problem A. Ample Syrup
https://code.google.com/codejam/contest/3274486/dashboard Problem The kitchen at the Infinite House ...
- Google Code Jam 2014 资格赛:Problem C. Minesweeper Master
Problem Minesweeper is a computer game that became popular in the 1980s, and is still included in so ...
随机推荐
- crt连接vitualbox中centos虚拟机
在virtalbox中安装了centos虚拟机后,在虚拟机中直接操作很是不方便,所以想用crt连接虚拟机, 1.打开virtualbox,设置-网络,网络连接2设置连接方式为“Bridged Adap ...
- Fedora 17配置ssh及Windows远程连接
转载自:http://nanjingjiangbiao-t.iteye.com/blog/1794213 Fedora 23 默认已经安装好openssh server了,不用再装不过默认情况下没有开 ...
- web附件中文名
response.setHeader("Content-Disposition", "attachement;filename="+URLEncoder.enc ...
- 转: Transact-sql游标使用详解~~很详细
/*原理:游标就是把数据按照指定要求提取出相应的数据集,然后逐条进行数据处理.1.1游标的概念 游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集. 使用游标(cursor)的一 ...
- Nexus 5完全拆解
Nexus 5,由LG制造,配备高通骁龙四核处理器,4.95英寸1080P显示屏,支持4G LTE,运行最新的Android 4.4 KitKat原生操作系统.国外著名拆解网站iFixit第一时间带来 ...
- Shared_from_this 几个值得注意的地方
shared_from_this()是enable_shared_from_this<T>的成员 函数,返回shared_ptr<T>.首先需要注意的是,这个函数仅在share ...
- Android 实现简单天气应用
引导页面,多个城市的天气,可以通过滑动来翻阅. 先看下截图: 1.城市天气界面 2.引导界面 应用引导页面 package org.qxj.iweather.page; import org.qxj. ...
- 汇编语言学习——第二章 寄存器(CPU工作原理)
1.一个典型的CPU由运算器.控制器.寄存器等器件组成,这些器件靠内部总线相连. 区别: 内部总线实现CPU内部各个器件之间的联系. 外部总线实现CPU和主板上其它器件的联系. 8086CPU有14个 ...
- UC/0S2之基础总结
堆栈,就是在存储器中按数据“后进先出(LIFO)[类比杯子]”的原则组织的连续存储空间,为了满足任务切换和响应中断保存CPU寄存器中的内容及存储任务私有数据的需要,每个任务都应该配有自己的堆栈, 注意 ...
- 融合python2和python3
很多情况下你可能会想要开发一个程序能同时在python2和python3中运行. 想象一下你开发了一个模块,成百上千的人都在使用它,但不是所有的用户都同时使用python 2和3.这种情况下你有两个选 ...