1408141706-hd-Moving Tables.cpp

来源:互联网 发布:周末网络国债理财 编辑:程序博客网 时间:2024/06/06 19:31

                                     Moving Tables

                                                Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
                                                                Total Submission(s): 19303    Accepted Submission(s): 6591


Problem Description
The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in the following figure.



The floor has 200 rooms each on the north side and south side along the corridor. Recently the Company made a plan to reform its system. The reform includes moving a lot of tables between rooms. Because the corridor is narrow and all the tables are big, only one table can pass through the corridor. Some plan is needed to make the moving efficient. The manager figured out the following plan: Moving a table from a room to another room can be done within 10 minutes. When moving a table from room i to room j, the part of the corridor between the front of room i and the front of room j is used. So, during each 10 minutes, several moving between two rooms not sharing the same part of the corridor will be done simultaneously. To make it clear the manager illustrated the possible cases and impossible cases of simultaneous moving.



For each room, at most one table will be either moved in or moved out. Now, the manager seeks out a method to minimize the time to move all the tables. Your job is to write a program to solve the manager’s problem.
 

Input
The input consists of T test cases. The number of test cases ) (T is given in the first line of the input. Each test case begins with a line containing an integer N , 1<=N<=200 , that represents the number of tables to move. Each of the following N lines contains two positive integers s and t, representing that a table is to move from room number s to room number t (each room number appears at most once in the N lines). From the N+3-rd line, the remaining test cases are listed in the same manner as above.
 

Output
The output should contain the minimum time in minutes to complete the moving, one per line.
 

Sample Input
3 4 10 20 30 40 50 60 70 80 2 1 3 2 200 3 10 100 20 80 30 50
 

Sample Output
102030
 


题目大意

      

著名的ACM(先进的电脑制造商)公司租了一个楼层的建筑物的形状如下图。

地板上有200个房间的北面和南面走廊。公司最近做了一个计划,制度改革。改革包括搬动很多房间里的桌子。由于走廊狭窄,所有的桌子都大,只有一个表可以通过走廊。一些计划需要进行高效运动。经理想出了以下计划:搬动一张桌子从房间到另一个房间可以在10分钟内。当移动台从一个房间i房间的j,用房间i和房间j前面走廊的中间部分。所以,每次10分钟,几个移动的两个房间的走廊不共享相同的部分之间将同时进行。要清楚经理举例说明了可能的情况和不可能的情况下同时移动。

每个房间,只有一张桌子可以移入或移出。现在,经理寻找一个最小化的时间将所有桌子移动的方法。你的任务是写一个程序来解决这个问题

 

注意细节

       给出的两个房间号,也可能是从大房间移到小房间,所以要将给出的两个房间号按从小到大排一下。

 

错误原因

       一开始我的思路是贪心,跟活动安排那个题差不多。活动安排那个题是在一天之内求最多活动的数量,而这道题我想着是每天都进行最多数量的活动,进行过的活动做标记,当所有活动都进行完之后所用的天数就是要求的时间。

测试数据都对,但是提交就是WA,无解了。。。后来求助学长,学长将下面桌子搬动的房间数倒着来提交结果是超时。当然,超时我可以理解,因为我也感觉自己的思路有点麻烦。

 

错误代码(严格的说是超时)

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct room{    int x,y;}rooms[250];int f(int a){    if(a%2==0)        return a-1;    else        return a;}bool cmp(room a,room b){    return a.y<b.y;}int main(){    int t,n;    int sta,end,i,j,k,temp,num;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i=0;i<n;i++)        {            scanf("%d%d",&sta,&end);            if(sta>end)            {                temp=sta;                sta=end;                end=temp;            }//一开始没有考虑到会出现从大房间移到小房间的情况                rooms[i].x=f(sta);            rooms[i].y=f(end);        }        sort(rooms,rooms+n,cmp);        num=0;        for(i=1;;i++)        {       /*    for(j=0;;j++)            */for(j=n-1;j>=0;j--)                          /*        if(rooms[j].x!=-1)   */if(rooms[j].y!=-1)                 {       /*           temp=rooms[j].y;  */temp=rooms[j].x;       /*           rooms[j].x=-1;    */rooms[j].y=-1;                    num++;                    break;                }       /*   for(k=j+1;k<n;k++)        */for(k=j-1;k>=0;k--)             /*       if(rooms[k].x>temp)   */if(rooms[k].y<temp)                {       /*           temp=rooms[k].y;  */temp=rooms[k].x;       /*           rooms[k].x=-1;    */rooms[k].y=-1;                    num++;                }            if(num==n)                break;        }        printf("%d\n",i*10);    }    return 0;}


 

解题思路

       学长给我讲了一个可简单的思路。先开一个数组,数组下标即表示房间号,然后移动桌子的时候,把每一次挪动桌子占用的房间对应的数组值都+1,然后找出重复次数最多的房间的重复次数就是要求的时间。

 

代码

#include<stdio.h>#include<string.h>int s[410];int f(int a){    if(a%2==0)        return a-1;    else        return a;}int main(){    int t,n;    int i,j,k,l;    int a,b;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        memset(s,0,sizeof(s));        for(i=0;i<n;i++)        {            scanf("%d%d",&a,&b);            if(a>b)            {                j=a;                a=b;                b=j;            }            a=f(a);            b=f(b);            for(k=a;k<=b;k++)                s[k]++;        }        l=0;        for(i=1;i<=400;i++)            if(l<s[i])                l=s[i];        printf("%d\n",l*10);    }    return 0;}



 

0 0