HDU1050-Moving Tables

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
  
  
10 20 30
 
 
题目大意:
在一座筒子楼中,两边各有200房间,编号交叉排列(一边全是奇数,另一半全是偶数),中间有走廊,现在有一些计划,就是各个房间的桌子需要相互搬动,由于走廊狭窄,所以有所交叉的走廊不能共享,而要分次行动,每一组桌子搬动,都要花费10分钟,不交叉的部分可以同时完成。
 
题目分析:
假设从1->399(或者2->400)的走廊是一条线段,每搬一张桌子(如从30号房间搬到40号房间),则线段30->40被重复了一次。如果另外再搬一张桌子(如从35号房间搬到45号房间),则线段35->45被重复了一次。而相同的线段35->40则被重复了两次。问题转化为求最大重复次数。那很好办了,一个201大小的数组表示走廊位置,初始化为0. 若30->40重复(30号房间搬桌子到40号房间),则对30,31,32……40号房间对应的走廊位置上都加1,第二次35->45,又对35->45号房间对应的走廊位置加1。全部完成后,找出走廊最大值的位置,乘以10分钟,则是所用时间。
 
代码:
#include<stdio.h>
#include<string.h>
int main() {
    int num[202],T,n,a,b,temp,i,j,t;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        memset(num,0,sizeof(num));
        for(i=0;i<n;i++) {
            scanf("%d %d",&a,&b);
            if(a>b) {
                temp=a;
                a=b;
                b=temp;
            }
            a=(a+1)/2;
            b=(b+1)/2;
            for(j=a;j<=b;j++)
                num[j]++;
        }
        for(i=1,t=0;i<=200;i++) {
            if(num[i]>t)
                t=num[i];
        }
        printf("%d\n",t*10);     
    }
    //system("pause");
    return 0;
}
      刚开始想的是和会议安排类似,用贪心算法即可,首先按照每一次移动所占用空间的结束位置最靠前排列,从前向后依次判断即可,但是判断的代码写成了:for(i=1,t=n*10;i<n;i++) {
	if(room[i].x>room[i-1].y)
		t-=10;
}
printf("%d\n",t); 但是看下面一组数据:131 73 119 13如果按照刚才的错误写法,就会输出30,而实际需要20,这是因为第一和第三可以同时进行!,所以讲代码作如下修改即可:#include<stdio.h>
#include<string.h>
int main() {
    int num[202],T,n,a,b,temp,i,j,t;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        memset(num,0,sizeof(num));
        for(i=0;i<n;i++) {
            scanf("%d %d",&a,&b);
            if(a>b) {
                temp=a;
                a=b;
                b=temp;
            }
            a=(a+1)/2;
            b=(b+1)/2;
            for(j=a;j<=b;j++)
                num[j]++;
        }
        for(i=1,t=0;i<=200;i++) {
            if(num[i]>t)
                t=num[i];
        }
        printf("%d\n",t*10);     
    }
    //system("pause");
    return 0;
}


 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值