[HDU 1050] Moving Tables (greedy)

Moving Tables

Chinese title

move the table

Problem Description

Dingba Xinao Training Center has recently rented a floor in Fuli Technology Building. The shape of this floor is as follows:

insert image description here

It can be seen from the picture that there is a corridor in the middle of this floor, and there are 200 rooms on each side, numbered as shown in the picture above.

Recently, Dingba Xinao Training Center has made internal organization adjustments, and some tables need to be moved from one room to another. Because the corridor is very narrow, but the tables are large, only one table can pass through the same corridor at a time.
Suppose it takes 10 minutes to move the table every time, regardless of the distance. At the same time, when you move the table from room i to room j, the corridor between room i and room j is occupied, that is to say, within each 10 minutes, multiple tasks cannot share the same corridor.

Now, Dad Ding wants to know: How much time is the minimum time needed to complete all the moving tasks?
 

Input

The input contains T sets of test cases.
Each set of test cases starts with a positive integer N (1<=N<=200), indicating the number of tables that need to be moved.
Next N lines, each line contains 2 positive integers s and t, indicating that a table needs to be moved from room s to room t.
 

Output

Calculate and output the minimum time required to complete all the handling tasks, each set of data occupies one 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

 
 

English original title

Link: HDU 1050 questions http://acm.hdu.edu.cn/showproblem.php?pid=1050
 

Moving Tables

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

 

Description

The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in the following figure.
insert image description here
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.
insert image description here
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

Source

Asia 2001, Taejon (South Korea)
 

train of thought

The first idea is greedy. Start moving from the front room, find tables that do not conflict with all the lines to be moved this time, and move these tables at one time until all the tables are moved.

the code

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

#define N 220
int s[N], t[N];

typedef struct a
{
    
    
    int s;
    int t;
}m;

m q[N];
bool f[N]; //用于标记是否搬了
bool cmp(m a, m b) //按开始时间排序
{
    
    
    if (a.s < b.s) return 1;
    else return 0;
}
int main()
{
    
    
    int t, ans;
    cin >> t;
    while (t--)
    {
    
    
        int n;
        cin >> n;
        memset(q, 0, sizeof(q));
        memset(f, 0, sizeof(f));
        ans = 0;

        for (int i = 0; i < n; i++)
        {
    
    
            cin >> q[i].s >> q[i].t;
            q[i].s = (q[i].s + 1) / 2;
            q[i].t = (q[i].t + 1) / 2;
            if (q[i].s > q[i].t) {
    
     //注意输入的数据可能大小需要调整
                int temp = q[i].s;
                q[i].s = q[i].t;
                q[i].t = temp;
            }
        }
        sort(q, q + n, cmp);
        
        for (int j = 0; j < n; j++)
        {
    
    
            int flag = 0;
            if (!f[j]) {
    
    
                f[j] = 1;
                m temp = q[j];
                int tmp = j;
                for (int k = j + 1; k < n; k++)
                {
    
    
                    if (!f[k] && q[k].s != temp.s && q[k].s > temp.t)
                    {
    
    
                        f[k] = 1, f[tmp] = 1;
                        tmp = k;
                        temp = q[k];
                    }
                }
                ans += 10;
            }

            for (int k = 0; k < n; k++)
            {
    
    
                if (f[k] == 0)
                {
    
    
                    flag = 1;
                    break;
                }
            }
            if (!flag) break;
        }
        cout << ans << endl;
    }
    return 0;
}

A more concise code

From https://www.cnblogs.com/springside6/archive/2012/05/02/2525060.html

#include<stdio.h>
#include<vector>
#include<iterator>
#include<algorithm>
using namespace std;
struct M{
    
    
	int s;
	int t;
};

bool comp(const M &m1, const M &m2){
    
    
	return m1.s < m2.s;	//按照开始的房间号排序
}

int main(){
    
    
	int T, s, t;
	scanf("%d", &T);
	while(T--){
    
    
		int n;
		vector<M> v;
		scanf("%d", &n);
		for(int i = 0; i < n; ++i){
    
    
			M m;
			scanf("%d%d", &s, &t);
			if(s > t){
    
    	//有可能从号码大的房间往回搬,若是,则交换s与t
				s = s ^ t;	//交换s,t
				t = s ^ t;	//相当于
				s = s ^ t;	//int tmp = s; s = t; t = tmp;
			}
			m.s = s;
			m.t = t;
			v.push_back(m);
		}
		sort(v.begin(), v.end(), comp);
		int ans = 0;
		for(vector<M>::iterator it = v.begin(); it != v.end();){
    
    	//从房间号最小的开始查找
			++ans;
			int t = (*it).t;
			for(vector<M>::iterator subit = it; subit != v.end();){
    
    	//找到与要搬的线路不冲突的桌子
				if((*subit).s > t && !((*subit).s - t == 1 && (*subit).s % 2 == 0)){
    
    	//注意对面房间的线路也是冲突的,比如5与6
					t = (*subit).t;
					subit = v.erase(subit);	//该桌子已搬完,删除
				}else
					 ++subit;	//否则继续查找下一张桌子
			}
			it = v.erase(it);	//删除
		}
		printf("%d\n", ans * 10);
	}
	return 0;
}

Another idea is to calculate the number of times each corridor needs to be used, and finding the maximum value is the desired answer.
insert image description here
It can be known that the intersecting place is the place of conflict, and the number of conflicts in each place is recorded, so the maximum number of conflicts is the number of times to be moved.

the code

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

int p[201];

int main()
{
    
    
    int T, ans;
    cin >> T;
    while(T --)
    {
    
    
        int n;
        cin >> n;
        int s,t;
        memset(p, 0, sizeof(p));
        ans = 0;
        for(int i = 0; i < n; i ++)
        {
    
    
            cin >> s >> t;
            s = (s + 1) / 2;
            t = (t + 1) / 2;
            if(s > t)
            {
    
    
                swap(s, t);
            }
            for(int j = s; j <= t; j++)
            {
    
    
                p[j]++;                
            }
        }
        for(int i = 1; i <= 200; i ++)
        {
    
    
            if(p[i] > ans) ans = p[i];
        }
        cout << ans*10 << endl;
    }
    
    
    return 0;
}

Guess you like

Origin blog.csdn.net/xxmy7/article/details/113442364