Fabled Rooks

Problem F: Fabled Rooks

We would like to place
n rooks, 1 ≤ n ≤ 5000, on a n×n board subject to the following restrictions

  • The i-th rook can only be placed within the rectangle given by its left-upper corner (xli,
    yli) and its right-lower corner (xri,
    yri
    ), where 1 ≤ in, 1 ≤ xli
    xrin, 1 ≤ yliyri
    n.
  • No two rooks can attack each other, that is no two rooks can occupy the same column or the same row.

The input consists of several test cases. The first line of each of them contains one integer number,
n, the side of the board. n lines follow giving the rectangles where the rooks can be placed as described above. The
i-th line among them gives xli, yli,
xri, and yri. The input file is terminated with the integer `0‘ on a line by itself.

Your task is to find such a placing of rooks that the above conditions are satisfied and then output
n lines each giving the position of a rook in order in which their rectangles appeared in the input. If there are multiple solutions, any one will do. Output
IMPOSSIBLE if there is no such placing of the rooks.

Sample input

8
1 1 2 2
5 7 8 8
2 2 5 5
2 2 5 5
6 3 8 6
6 3 8 5
6 3 8 8
3 6 7 8
0

Output for sample input

1 1
5 8
2 4
4 2
7 3
8 5
6 6
3 7

题意:在棋盘上将8棋子放入棋盘中;且不能再同一行或者同一列;还要满足的一个条件就是他给出的每一个区域都必有一个棋子;
方法:可以先看行,再看列;再输入测试数据是给出来的答案可能不一样,但是不影响最后的结果;

# include <cstdio>
# include <iostream>
using namespace std;

int x1[5005],x2[5005],y1[5005],y2[5005],x[5005],y[5005];

bool solve(int *x1,int *x2,int *x,int n)
{
    fill(x,x+n,-1);    //将值置为-1;
    for(int cool=1;cool<=n;cool++)    //列举要填的数:
    {
        int root=-1,Max=n+1;
        for(int i=0;i<n;i++)
            //判断边界,找出下边界最小的那个;
            if(x[i]<0 && x2[i]<Max && x1[i] <= cool )    { root=i;    Max=x2[i]; }
        if(root<0||cool>Max)    return false;    //越界或者没有这个区间;
        x[root]=cool;
    }
    return true;
}

int main ()
{
    int n,i,j;
    while(cin>>n&&n)
    {
        for(i=0;i<n;i++)
            scanf("%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i]);
        if(solve(x1,x2,x,n)&&solve(y1,y2,y,n))
            for(i=0;i<n;i++)    printf("%d %d\n",x[i],y[i]);
        else
            printf("IMPOSSIBLE\n");
    }
    return 0;
}

时间: 2024-10-05 04:58:22

Fabled Rooks的相关文章

L - Fabled Rooks(中途相遇法和贪心)

Problem F: Fabled Rooks We would like to place n rooks, 1 ≤ n ≤ 5000, on a n×n board subject to the following restrictions The i-th rook can only be placed within the rectangle given by its left-upper corner (xli, yli) and its right-lower corner (xri

uva11134 - Fabled Rooks(问题分解,贪心法)

这道题非常好,不仅用到了把复杂问题分解为若干个熟悉的简单问题的方法,更是考察了对贪心法的理解和运用是否到位. 首先,如果直接在二维的棋盘上考虑怎么放不好弄,那么注意到x和y无关(因为两个车完全可以在同一条斜线上,这点和皇后问题不一样),那么就可以分别考虑两个一维的问题:这是一种区间选点问题,在每个区间里都只选一个点,最后这些点分别是1到n.这就联想到这样一个经典的贪心法解决的区间选点问题:数轴上有n个闭区间[ai,bi],选取尽量少的点,使得每个区间都至少含有一个点.这个问题的解决方法就是把所有

UVA - 11134 Fabled Rooks[贪心 问题分解]

UVA - 11134 Fabled Rooks We would like to place n rooks, 1 ≤ n ≤ 5000, on a n × n board subject to the following restrictions The i-th rook can only be placed within the rectan- gle given by its left-upper corner (xli,yli) and its right- lower corner

01_传说中的车(Fabled Rooks UVa 11134 贪心问题)

问题来源:刘汝佳<算法竞赛入门经典--训练指南> P81: 问题描述:你的任务是在n*n(1<=n<=5000)的棋盘上放n辆车,使得任意两辆车不相互攻击,且第i辆车在一个给定的矩形R之内. 问题分析:1.题中最关键的一点是每辆车的x坐标和y坐标可以分开考虑(他们互不影响),不然会变得很复杂,则题目变成两次区间选点问题:使得每辆车在给定的范围内选一个点,任何两辆车不能选同一个点.  2.本题另外一个关键点是贪心法的选择,贪心方法:对所有点的区间,按右端点从小到大排序:每次在一个区间

UVa 11134 Fabled Rooks(贪心)

题意  在n*n的棋盘上的n个指定区间上各放1个'车'  使他们相互不攻击   输出一种可能的方法 行和列可以分开看  就变成了n个区间上选n个点的贪心问题  看行列是否都有解就行   基础的贪心问题  对每个点选择包含它的最优未使用空间 #include <bits/stdc++.h> using namespace std; const int N = 5005; int xl[N], yl[N], xr[N], yr[N], x[N], y[N], n; bool solve(int a

uva 11134 - Fabled Rooks(主要在贪心方法及其实现)

#用到了贪心方法. #这个贪心刚开始想错了方法,后来想到了新的方法,AC 刚开始错在了按左端点升序排序并从左往右取最左端能取的格子,这个方法显然不能符合要求 比如下面这组数据: 2 1 1 3 3 1 1 3 3 2 2 2 2 错误代码: #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; struct note {

UVA 11134 - Fabled Rooks(贪心 / 二分图 + 线段树优化连边)

题目地址:Fabled Rooks 题目大意:n * n 的棋盘上摆了 n <=10^5 个车,让他们两两不攻击,每个车必须摆在一个给定矩形里,给出一个解决方案? 1. 贪心 由于行列互不影响, 所以可以分两遍求.第一遍确定每个车的行数,第二遍确定列数. 以行为例,若从左到右扫描,则按照区间的右端点升序排序,因为如果扫到一个位置两枚棋子都可以放,则选择右端点较小的那个(右端点大的后面还有机会). 2. 二分图匹配 有个毒瘤老师把题目改成了这样:n * n 的棋盘上摆了 n <=10^5 个车,

UVa 11134 - Fabled Rooks——[问题分解、贪心法]

We would like to place n rooks, 1 ≤ n ≤ 5000, on a n × n board subject to the following restrictions • The i-th rook can only be placed within the rectangle given by its left-upper corner (xli, yli) and its rightlower corner (xri, yri), where 1 ≤ i ≤

General Problem Solving Techniques [Intermediate-1]~D - Fabled Rooks

We would like to place n rooks, 1 ≤ n ≤ 5000, on a n × nboard subject to the following restrictions• The i-th rook can only be placed within the rectanglegiven by its left-upper corner (xli, yli) and its rightlowercorner (xri, yri), where 1 ≤ i ≤ n,