1395:煩人的幻燈片(slides)
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 1625 通過數: 891
【題目描述】
李教授將於今天下午作一次非常重要的演講。不幸的事他不是一個非常愛整潔的人,他把自己演講要用的幻燈片隨便堆在了一起。因此,演講之前他不得不去整理這些幻燈片。作爲一個講求效率的學者,他希望儘可能簡單地完成它。教授這次演講一共要用n張幻燈片(n≤26),這n張幻燈片按照演講要使用的順序已經用數字1~n編了號。因爲幻燈片是透明的,所以我們不能一下子看清每一個數字所對應的幻燈片。
現在我們用大寫字母A,B,C……再次把幻燈片依次編號。你的任務是編寫一個程序,把幻燈片的數字編號和字母編號對應起來,顯然這種對應應該是唯一的;若出現多種對應的情況或是某些數字編號和字母編號對應不起來,我們稱對應是無法實現的。
【輸入】
第一行只有一個整數n,表示有n張幻燈片,接下來的n行每行包括4個整數xmin,xmax,ymin,ymax(整數之間用空格分開)爲幻燈片的座標,這n張幻燈片按其在文件中出現的順序從前到後依次編號爲A,B,C……,再接下來的n行依次爲n個數字編號的座標x,y,顯然在幻燈片之外是不會有數字的。
【輸出】
若是對應可以實現,輸出文件應該包括n行,每一行爲一個字母和一個數字,中間以一個空格隔開,並且每行以字母的升序排列,注意輸出的字母要大寫並且定格;反之,若是對應無法實現,在文件的第一行頂格輸出None即可。首行末無多餘的空格。
【輸入樣例】
4
6 22 10 20
4 18 6 16
8 20 2 18
10 24 4 8
9 15
19 17
11 7
21 11
【輸出樣例】
A 4
B 1
C 2
D 3
思路:類拓撲排序,給區間編號,然後有一個點在其範圍,這個區間的入度就增加,每次遍歷所有區間,然後挑出入度爲1的區間,數組記錄,因爲他要求按區間順序輸出
#include<cstdio>
#include<iostream>
using namespace std;
struct node{
int xi,xa,yi,ya;
}q[30];
struct point{
int x,y;
}p[30];
int n,sum;
int du[30],vis[30][30],ans[30];
void find(int x){
sum++;du[x]--;
for(int i = 1;i <= n;i++) if(vis[x][i]) {
ans[i]=x;
vis[x][i]=0;
for(int j = 1;j <= n;j++){
if(vis[j][i]){
du[j]--;
vis[j][i] = 0;
if(du[j] == 1) find(j);
}
}
break;
}
return ;
}
int main(){
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%d %d %d %d",&q[i].xi,&q[i].xa,&q[i].yi,&q[i].ya);//記錄每一張幻燈片的範圍
}
for(int i=1;i<=n;i++){
scanf("%d %d",&p[i].x,&p[i].y);//記錄數字座標
int cnt = 0;
for(int j = 1;j <= n;j++){
if(p[i].x <= q[j].xa && p[i].x >= q[j].xi &&
p[i].y <= q[j].ya && p[i].y >= q[j].yi){
vis[i][j] = 1,cnt++;//遍歷一遍看看數字是否可能在幻燈片上 一個數字的位置可能有幾張幻燈片,順便個他們打個標記
}
}
du[i]=cnt;
}
for(int i = 1;i <= n;i++) if(du[i] == 1) find(i);
if(sum < n) printf("None");//如果一個數字沒有與之對應的 那他在所有的幻燈片之外 就錯了
else for(int i = 1;i <= n;i++)
printf("%c %d\n",char(i-1+'A'),ans[i]);
return 0;
}