Sicily 1193 Up the Stairs

来源:互联网 发布:逆光源网络剧百度云盘 编辑:程序博客网 时间:2024/05/17 05:14

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

John is moving to the penthouse of a tall sky-scraper. He packed all his stuff in boxes and drove them to the entrance of the building on the ground floor. Unfortunately the elevator is out of order, so the boxes have to be moved up the stairs.
Luckily John has a lot of friends that want to help carrying his boxes up. They all walk the stairway at the same speed of 1 floor per minute, regardless of whether they carry a box or not. The stairway however is so narrow that two persons can't pass each other on it. Therefore they deciced to do the following: someone with a box in his hands is always moving up and someone empty-handed is always moving down. When two persons meet each other somewhere on the stairway, the lower one (with a box) hands it over to the higher one (without a box). (And then the lower one walks down again and the higher one walks up.) The box exchange is instantaneous. When someone is back on the ground floor, he picks up a box and starts walking up. When someone is at the penthouse, he drops the box and walks down again.

After a while the persons are scattered across the stairway, some of them with boxes in their hands and some without. There are still a number of boxes on the ground floor and John is wondering how much more time it will take before all the boxes are up. Help him to find out!

Input

One line with a positive number: the number of test cases. Then for each test case:

  • One line with three numbers N, F, B with 1 ≤ N,F ≤ 1000 and 1 ≤ B ≤ 1000000: the number of persons, the number of floors (0=ground floor, F=penthouse) and the number of boxes that are still on the ground floor.
  • N lines with two numbers fi and bi with 0 ≤ fi ≤ F and bi = 0 or bi = 1: the floors where the persons are initially and whether or not they have a box in their hands (1=box, 0=no box).

Output

One line with the amount of time (in minutes) it will take to get all the remaining boxes to the penthouse.

Sample Input

23 10 50 00 00 02 5 12 13 0

Sample Output

308

Solution

给出t个case,每个case给出n个人,f层楼,b个箱子。fi和bi代表每个人的初始楼层数和有没有箱子,bi为1代表有箱子,0则没有。问把所有箱子搬上楼的最短时间。

比较要思考的模拟题,关键在于碰头就传递箱子并且转向,这里没有特殊的人物属性附加,那么我们就可以假设这两个人直接交换了位置,那个楼梯单个人的限制就被打破了。

打破了限制之后,题目就变成了轮流搬箱子上楼了,然后计算最短的时间,直接模拟就ok啦。

我在直接用循环模拟的时候发现每次搬上去再搬下来的时候都是时间是2*f,最后一次的时候不用再下楼,就是用时是f,模拟的时候注意第一次到领箱子的地方的时间要排序,因为是按先来后到领箱子的。

找到了规律之后就发现可以直接归纳的,只有两种情况

1. b%n=0 也就意味着刚刚好每个人搬一样多的箱子数,那么最短时间就是最慢到达领箱子的地方的那个人把所有箱子搬上去的时间,注意是2*f*(b/n)-f,不用再下楼了;

2. b%n!=0 有些人搬多一些箱子,这些人比其他人的搬箱子时间多了2*f(其他人不用下楼再上楼)这是远大于初始时间的,就以为着最短的耗时一定是初始时第b%n+1个人加上搬箱子的时间2*f*(b/n)+f;

关于轮流的话,就算第一个人和第二个人同时出发也是无所谓的,因为楼梯的限制被“打破”了。


#include <cstdio>#include <algorithm>#include <cstring>int human[1005];int main(){  int t;  scanf("%d", &t);  while (t--)  {    int i, j, n, f, b, fi, bi, ans = 0;    memset(human, 0, sizeof(human));    scanf("%d%d%d", &n, &f, &b);    for (i = 0; i < n; ++i)    {      scanf("%d%d", &fi, &bi);      if (bi) human[i] = 2 * f - fi;//搬上去搬下来      else human[i] = fi;    }    std::sort(human, human + n);//初始时间排序    fi = b / n;    bi = b % n;    ans += fi * 2 * f;    if (bi) ans += human[bi-1] + f;    else ans = ans - f + human[n-1];//最后一个人    printf("%d\n", ans);  }  return 0;}


0 0