1. 程式人生 > >11134-Fabled Rooks【貪心 + 優先佇列 + 思想轉化】

11134-Fabled Rooks【貪心 + 優先佇列 + 思想轉化】

這題主要學習了一下貪心的方法,和優先佇列priority_queue的使用

貪心策略就是 每次 左邊界 小的 並且 右邊界 小的出佇列,其次需要根據位置不斷更新左邊邊界值

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<stack>
#include<iostream>
#include<queue>
#include<set>
#include<vector>
#include<cmath>
using namespace std;
#define MAXD 5000 + 100
struct Car{
    int l,r;
    int ID;
    friend bool operator < (Car p,Car q){
        if(p.l != q.l){
            if(p.l > q.l) return true;
            else
            return false;
        }
        else {
            if(p.r > q.r) return true;
            else
            return false;
       }
    }
}car[MAXD];
int n;
int main(){
    while(scanf("%d",&n) && n){
        priority_queue<Car>q1;
        priority_queue<Car>q2;
        for(int i = 0 ; i < n ; i++){
            Car temp1,temp2;
            scanf("%d%d%d%d",&temp1.l,&temp2.l,&temp1.r,&temp2.r);
            temp1.ID = i + 1;  temp2.ID = i + 1;
            q1.push(temp1);
            q2.push(temp2);
        }
        int now_pos = 1;
        int ok = 1;
        int _x[MAXD],_y[MAXD];
        while(!q1.empty()){
            Car t = q1.top();
            q1.pop();
            if(t.l < now_pos){
                t.l = now_pos;
                q1.push(t);
            }
            else if(t.l > now_pos || t.r < now_pos){
                ok = 0;
                break;
            }
            else{
                _x[now_pos++] = t.ID;
            }
        }
        now_pos = 1;
        if(ok)while(!q2.empty()){
            Car t = q2.top();
            q2.pop();
            if(t.l < now_pos){
                t.l = now_pos;
                q2.push(t);
            }
            else if(t.l > now_pos || t.r < now_pos){
                ok = 0;
                break;
            }
            else{
                _y[now_pos++] = t.ID;
            }
        }
        int ans_x[MAXD],ans_y[MAXD];
        for(int i = 1 ; i <= n ; i++){
            int t = _x[i];
            ans_x[t] = i;
            for(int j = 1 ; j <= n ; j++)if(_y[j] == t){
                ans_y[t] = j;
                break;
            }
        }
        if(ok) for(int i = 1 ; i <= n ; i++)
          printf("%d %d\n",ans_x[i],ans_y[i]);
        else
          printf("IMPOSSIBLE\n");
    }
    return 0;
}

 

相關推薦

11134-Fabled Rooks貪心 + 優先佇列 + 思想轉化

這題主要學習了一下貪心的方法,和優先佇列priority_queue的使用 貪心策略就是 每次 左邊界 小的 並且 右邊界 小的出佇列,其次需要根據位置不斷更新左邊邊界值 #include<cstdio> #include<cstring> #inc

UVA 11134 Fabled Rooks 貪心+問題分解

題意: 在一個n*n的棋盤中放置 n個棋子,每個棋子有固定的放置範圍,在滿足放置範圍的情況下,放置的棋子橫向和縱向不能有第二個棋子;輸出棋子的放置位置或者 impossible; 思路: 解這題的關鍵就是問題的分解,如果能想到問題的分解方法的話,就比較容易做了;因為

UVa 11134 Fabled Rooks貪心優先佇列

題目連結 題目大意:     在一個棋盤上,放置N個國際象棋的城堡,每個城堡給出可以放置的範圍,要求這些城堡不能相互攻擊到,求這些城堡的擺放方案。 解題思路:     這題非常關鍵的一點就是橫縱座標可以分開獨立考慮。對於每一個方向,我們維護一個下限小(其次上線小)的區間

UVA 11134 Fabled Rooks貪心的妙用+memset誤用警示)

\n UC 錯誤 百度 函數傳參 用法 min 開始 != 題目鏈接: https://cn.vjudge.net/problem/UVA-11134 1 /* 2 問題 輸入棋盤的規模和車的數量n(1=<n<=5000),接著輸入n輛車的所能在的矩陣

POJ2431 Expedition貪心+優先佇列

【問題描述】        一群奶牛搶了一輛卡車決定前往樹林裡探險。但是由於他們的駕駛技術太糟,油箱在路上弄破了,所以他們每前進一個單位的路程就會漏掉一個單位的油。為了修好油箱,奶牛們必須前往最近的城市(不會超過1000000單位路程)。在當前位置和城市之間有N個加油站,

CodeForces 137C貪心+優先佇列

這種區間的貪心好像都出“爛”了? 不過還是想寫一下。。。 先按照區間左端點排序一下,然後搞個優先佇列維護當前最小的右端點。 #include <bits/stdc++.h> using n

(白書訓練計劃)UVa 11134 Fabled Rooks貪心

這題因為行與列是無關的,互無影響的。所以可以將行或列分開來計算。這就相當於轉化成了在期間[1,n]內選擇n個不同的整數,使得第i個整數在閉區間[Li,Ri]內。這就轉換成了一個貪心問題了。但是注意不能先按照左端點排序,再按右端點排序,然後儘量往左邊放,比如,(1,1),(

864 A B C模擬 D貪心+優先佇列

A - Fair Game Petya and Vasya decided to play a game. They have n cards (n is an even number). A single integer is written on eac

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 with

UVa 11134 - Fabled Rooks 優先隊列,貪心 難度: 0

所在 n皇後 時間 com pro 比較 php 現在 online 題目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&am

51Nod - 1163最高的獎勵 (貪心+優先佇列 或 妙用並查集)

題幹: 有N個任務,每個任務有一個最晚結束時間以及一個對應的獎勵。在結束時間之前完成該任務,就可以獲得對應的獎勵。完成每一個任務所需的時間都是1個單位時間。有時候完成所有任務是不可能的,因為時間上可能會有衝突,這需要你來取捨。求能夠獲得的最高獎勵。 Input 第1行:一個數N,表示

Codeforces-140CNew Year Snowmen(貪心+優先佇列、二分)

As meticulous Gerald sets the table and caring Alexander sends the postcards, Sergey makes snowmen. Each showman should consist of three snowballs:

POJ2786-Keep the Customer Satisfied(貪心 + 優先佇列,姿勢不對就要跪)

按照截止日期排序,之後一個一個遍歷,記錄當前時間,如果當前時間大於截止時間,那麼從選過的任務裡刪除一個花費最大的任務 優先佇列維護 14038525 2786 Accepted 11168K 1016MS C++ 905B 2015-04-02 12:22:16 #inc

UVa 11134 Fabled Rooks 算法分析

端點 處理 我們 example lob problem 經典 一個點 本質 難度:β 用時:0 題目:?? 代碼:?? 這是一道區間貪心題。 題目都不用花心思建模了。要求相當明確。就是要把 n 個點放在 一個 n x n 的網格裏,要求點與點不能共行或共列,每個點

51Nod 1191 消滅兔子 (貪心+優先佇列)

  對兔子血量排個降序(即從血多的開始殺),對弓箭按傷害值降序排。對每一隻兔子,都要把能殺死他的弓箭的價值入隊,入隊完畢以後,如果佇列為空說明這個兔子殺不了,不為空說明這個兔子能殺,那就從能殺這個兔子的弓箭裡選個最便宜的,按照這樣對n只兔子操作 #include<bits/s

#120-[貪心,優先佇列]數列極差

Description 佳佳的老師在黑板上寫了一個由 n 個正整陣列成的數列,要求佳佳進行如下操作:每次擦去其中的兩個數 a 和 b,然後在數列中加入一個數 a×b+1,如此下去直至黑板上剩下一個數為止,在所有按這種操作方式最後得到

POJ - 3190 貪心+優先佇列

今天,吃飯,被SW教育了一波,堆是完全二叉樹,堆是完全二叉樹,堆是完全二叉樹,重要的事情說三遍。 優先佇列是堆,priority_queue——一個強大的STL,下面先介紹priority_queue的用法。 #include <iostream> #include <

[貪心 優先佇列] 兩步驟完成多項工作總用時最短 HDU6000

Wash Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 64000/64000 K (Java/Others) Total Submission(s): 2492  

貪心+優先佇列之更改優先順序-hdu1896

題目描述: 題目理解:   Sempr從位置0往前走,一路上他會遇到石子,如果這顆石子是他遇到的第奇數顆石子,那麼他就把石子往前扔出去,如果他遇到的是第偶數顆石子,他會把它留在原地。需要注意的是,Sempr前面扔出去的石子,會繼續作為後續會遇到的石子。如果在一個位置上有多顆石子,那麼選出扔的最遠的那顆

UVA—11134 Fabled Rooks 傳說中的車

UVA-11134 Fabled Rooks 傳說中的車 剛開始時想直接用回溯法過,試了兩種回溯方法都超時了。 後來用貪心法寫了一遍,老是WA,卡了差不多兩小時發現自己輸出中的IMPOSSIBLE寫成IMPOSSBILE了,改了之後就AC了。難受。 總的來說還是要注意細節。 對於題目