题意:

现在有一个矩形,矩形碎成了n块玻璃。每块玻璃都是一个三角形,现在给出每个三角形的三个顶点,问按什么样的顺序,将三角形从上往下依次放入矩形,可以构成原来的玻璃。

这里需要注意题意中明确说了三角形的每一条边最多只会有一个相邻三角形,比赛的时候没看到这句话,然后整道题毫无头绪,哭了...实则不难。

思路:

然后我们来考虑如何写这题。稍微模拟一下就会知道,对于边PQ来说,只有两个三角形a、b是这条边的相邻三角形。而b在这条边的下面,而a在这条边上面。因此b需要在a之前放入,由此就可以想到拓扑排序。

map<line,int> mp,对每条边记一个其所属的三角形。依次读入每个三角形,建出每个三角形的三条边,然后判断第三个点在其对应边的上方还是下方。当 mp.find(line) != mp.end() 时,如果当前点在line的上方,则mp[line]对应的三角形向当前三角形建有向边。若在下方,则相反。

建完边之后跑拓扑排序,找出所有度数为0的点加入队列,依次取出,删去其连接的边,再将删去过程中度数变为0的点加入队列,直到所有点都被取出为止。本题即可解决。

反思:

这并不是一道很难的题,建图拓扑的思路比赛的时候也想到了,但是由于题目没有看清还是错失了AC的机会。在之后的比赛中,当题目完全没有头绪,而且场上过题人数不断增多的时候,一定要重新审视一下题干,千万不要再因为题意的问题而懊悔。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <algorithm>
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x) cout << "x: " << x << endl;
#define LOG2(x,y) cout << "x: " << x << ", y: " << y << endl;
#define pi acos(-1.0)
#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y)) //向量(p1,p2)与(p1,p3)叉乘
#define crossOp(p1,p2,p3) sign(cross(p1,p2,p3)) //判断正负,顺时针为负, 为0则代表三点共线
using namespace std;//实数比较
typedef double db;
const db EPS = 1e-9;
const int N = 1e6+1000;
inline int sign(db a) {return a < -EPS ? -1 : a > EPS; } //返回-1表示a < 0, 1表示a > 0, 0表示a = 0
inline int cmp(db a, db b) {return sign(a-b); } //返回-1表示a < b, 1表示a > b,0表示 a==bint n,head[N],tot,deg[N];
struct Edge{int to,next;
}e[3*N];void add(int u,int v){e[++tot].to = v, e[tot].next = head[u], head[u] = tot;
}//点类
struct Point {db x,y;Point() {}Point(db _x, db _y) : x(_x), y(_y) {}Point operator-(Point p) { return {x-p.x, y-p.y}; }db dot(Point p) { return x*p.x+y*p.y; } //点积db det(Point p) { return x*p.y-y*p.x; } //叉积bool operator<(Point p) const {int c = cmp(x, p.x);if (c) return c == -1; //先判断x大小return cmp(y, p.y) == -1; //再判断y大小}bool operator==(Point p) const {return cmp(x, p.x) == 0 && cmp(y, p.y) == 0;}bool operator!=(Point p) const{return (cmp(x, p.x) || cmp(y,p.y));}
};struct Line {Point s,e;Line() {}Line(Point _s, Point _e) : s(_s), e(_e) {}bool operator == (Line v) { return (s == v.s) && (e == v.e); }void adjust() { if(e<s) swap(s,e); }// 点和直线关系,1在上方,2在下方,3在直线上int relation(Point p) {int c = sign((p-s).det(e-s));if(c < 0) return 1;else if(c > 0) return 2;else return 3;}bool operator<(Line l) const {if(s != l.s) return s < l.s;else return e < l.e;}
};map<Line,int > mp; //mp[line]表示直线属于哪个三角形void solve()
{queue<int> q;while(q.size()) q.pop();rep(i,1,n) if(deg[i] == 0) q.push(i);int cnt = 0;while(q.size()){int x = q.front(); q.pop(); cnt++;printf("%d",x);if(cnt == n) printf("\n");else printf(" ");for(int i = head[x]; i; i = e[i].next){int y = e[i].to;deg[y]--;if(deg[y] == 0) q.push(y);}}
}int main()
{int _; scanf("%d",&_);while(_--){mp.clear();scanf("%d",&n);tot = 0;rep(i,0,n) head[i] = 0, deg[i] = 0;rep(i,1,n){Point p[4];rep(j,1,3) scanf("%lf %lf",&p[j].x,&p[j].y);Line l[4];l[1] = {p[2],p[3]}, l[2] = {p[1],p[3]}, l[3] = {p[1],p[2]}; rep(j,1,3){l[j].adjust();int rel = l[j].relation(p[j]); //上下方if(mp.find(l[j]) != mp.end()){if(rel == 1) add(mp[l[j]],i), deg[i]++;else if(rel == 2) add(i,mp[l[j]]), deg[mp[l[j]]]++;}else mp[l[j]] = i;}}solve();}return 0;
}

【2011-2012 ACM-ICPC Pacific Northwest Regional Contest】Collateral Cleanup【建图拓扑排序】相关推荐

  1. 2016 ACM / ICPC Asia dalian Regional Contest 题解(11 / 11)【每日亿题2021 / 2 / 17】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A .(2017 ACM ICPC dalian H)To begin or not to be ...

  2. 2017 ACM ICPC Asia Shenyang Regional Contest 题解(10 / 13)【每日亿题2 / 16】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A.(2017 ICPC shenyang I)Little Boxes B.(2017 ICP ...

  3. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)

    gdcpc前一天上午搞了场训练,水题挺多,还算增强信心.(这么简单的题目居然还是div1,这赛区-- 最终9题,平均每人3题,我写ACF.被hry压了一道E (难受啊. 下午去中大试机,win7系统就 ...

  4. 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) 【部分题解】

    A:因为删除是不计入操作次数的,所以转化一下就是求最长上升子序列,简单dp. 设dp[i]表示前i个字符能凑成上升子序列的最大长度,dp[i] = max(dp[j]+1, dp[i]) [j < ...

  5. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) - D Count The Bits

    题目链接 Given an integer k and a number of bits b (1 ≤ b ≤ 128), calculate the total number of 1 bits i ...

  6. Gym 101982 (2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) )

    传送门: Problem A 温暖的签到题 #include<bits/stdc++.h> using namespace std; const int maxn=1007; char s ...

  7. 2013-2014 ACM-ICPC Pacific Northwest Regional Contest题解

    ProblemSet A by ? B by ? 先Floyd求出两两之间最短路. 二分答案,新建一个图,<=x点对连距离为1的边 再施展Floyd,判断,最远两点距离<=k C by ? ...

  8. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)DCount The Bits(dp/数位dp)

    D Count The Bits 题意: 输入k,b(1≤k≤1000,1≤b≤128);k,b(1\leq k\leq 1000,1\leq b\leq128);k,b(1≤k≤1000,1≤b≤1 ...

  9. The 2019 ICPC Asia Shanghai Regional Contest

    The 2019 ICPC Asia Shanghai Regional Contest 题号 题目 知识点 A Mr. Panda and Dominoes B Prefix Code C Maze ...

  10. 2018 ICPC Asia Jakarta Regional Contest

    2018 ICPC Asia Jakarta Regional Contest 题号 题目 知识点 难度 A Edit Distance B Rotating Gear C Smart Thief D ...

最新文章

  1. Java项目:企业人事管理系统(java+SSM+jsp+mysql+maven)
  2. 循环神经网络RNN的基本组件(五)
  3. c#组元(Tuple)的使用
  4. nginx实现大小写字母转换(ngx_http_lower_upper_case模块)
  5. shutdown小程序
  6. 男人要明白的22件事
  7. 装饰效果(最大连续字段和)
  8. 山西计算机应用能力,《山西省计算机应用能力考试练习系统》使用说明
  9. 如何在 Mac 上打开或关闭专注模式?
  10. 进程,线程,协程的区别与联系
  11. VC实现文件拖拽获取文件名
  12. 网络工程师下午考试试题专题专解
  13. 浅谈大数据和人工智能
  14. 桌面智能分析产品+“智同211”计划,永洪科技打造数据价值生态圈!
  15. 父级fixed_CSS3--改变固定定位(fixed)的父级定位元素
  16. rk3328或树莓派开发板系统镜像备份制作剪裁
  17. ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!)
  18. Python运用循环实现模拟登录
  19. 网站变灰,6行代码,通通变灰
  20. Java合并两个List并去掉重复项的几种做法

热门文章

  1. apache高性能配置
  2. Spring Boot入门(1)-第一个Spring Boot应用
  3. STC学习:八位数码管+流水灯
  4. python列表语法_python学习之列表语法
  5. OpenCV-图像处理(06、调整图像亮度与对比度)
  6. 一百分成3 3 4怎么用计算机算,计算机组成原理试卷三
  7. y空间兑换代码_如何让Python代码加速运行?
  8. php解决中文乱码的函数,php 中解决json中文乱码的函数_PHP教程
  9. 安卓桌面软件哪个好_有哪些好用的手机记事本软件?安卓手机便签哪个好用?
  10. HP 滤波 (Hodrick Prescott Filter)