UVALive 7461 Separating Pebbles (计算几何)
Separating Pebbles
题目链接:
http://acm.hust.edu.cn/vjudge/contest/127401#problem/H
Description
http://7xjob4.com1.z0.glb.clouddn.com/1e1638de1146450534631815cbf822c6
Input
The first line of the input contains an integer K (K ≤ 20) indicating the number of test cases. The first
line of each test case consists of an integer N (N ≤ 250) indicating the number of pebbles. The next
N lines each contains a triplet (x, y, c), where x and y represent the x and y coordinates (all integers,
0 ≤ x, y ≤ 150) of a pebble point, and c represents the type of pebble: ‘o’ denoted by ‘0’ and ‘+’
denoted by ‘1’.
Output
For each test case, output ‘1’ if Dr. Y can separate the pebbles with a single straight line; if not, output
‘0’.
Sample Input
2
5
1 2 0
2 1 0
4 3 1
5 4 1
6 3 1
4
1 2 0
2 1 0
1 1 1
2 2 1
Sample Output
1
0
##题意:
给出平面上的两类点,判断是否能画一条直线将两类点完全分割开来.
##题解:
枚举任意两点组成的直线, 除了在直线上的点以外,若其余点满足分居两侧的要求,那么我只要稍微旋转一下这条直线就能满足要求.
对直线上点的特殊考虑:当直线上有若干点时,如果出现两个'o'点中间夹一个'x'的情况是无法旋转的.
所以能旋转的条件是直线上不会出现两种类型的点间隔分布.
对重点的特殊考虑:如果有重点的话,特判可能会比较多,所以干脆一开始对所有点去重. 若有两个不同类型的点重叠,那么一定不能划分.
(坑爹的是,题目的数据好像并没有重复点,在uDebug上跑类型不同的重点居然输出1).
不知不觉就打了5000B的代码,稍有点繁琐...
##代码:
``` cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define double long long
#define eps 1e-8
#define maxn 300
#define mod 100000007
#define inf 0x3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std;
struct Point{
double x,y;
int tp;
Point(){}
Point(double tx,double ty) {x=tx;y=ty;}
bool operator<(const Point& b)const
{
if(x==b.x) return y<b.y;
return x<b.x;
}
}tmp[maxn];
vector p;
struct Line{
Point a,b;
};
int sign(double x)
{
if(!x) return 0;
return x<0? -1:1;
}
double xmul(Point p0,Point p1,Point p2)
{return (p1.x-p0.x)(p2.y-p0.y)-(p2.x-p0.x)(p1.y-p0.y);}
bool is_inline(Point a, Point b, Point c) {
return xmul(a,b,c) == 0;
}
/判两点在线段异侧,点在线段上返回0/
int opposite_side(Point p1,Point p2,Line l)
{
return sign(xmul(p1,l.a,l.b)*xmul(p2,l.a,l.b))<0;
}
int same_side(Point p1,Point p2,Line l)
{
return sign(xmul(p1,l.a,l.b)*xmul(p2,l.a,l.b))>0;
}
/判断两点是否重合/
int equal_point(Point p1,Point p2)
{
return (sign(p1.x-p2.x)0)&&(sign(p1.y-p2.y)0);
}
int vis[200][200];
int main(int argc, char const *argv[])
{
//IN;
int t; cin >> t;
while(t--)
{
int n; scanf("%d", &n);
memset(vis, -1, sizeof(vis));
p.clear(); p.push_back(Point(0,0));
bool flag = 1;
int m = 0;
for(int i=1; i<=n; i++) {
scanf("%lld %lld %d", &tmp[i].x, &tmp[i].y, &tmp[i].tp);
}
//sort(p+1, p+1+n);
/*去重*/
for(int i=1; i<=n; i++) {
if(vis[tmp[i].x][tmp[i].y] == -1) {
vis[tmp[i].x][tmp[i].y] = tmp[i].tp;
p.push_back(tmp[i]);
m++;
} else {
if(vis[tmp[i].x][tmp[i].y] != tmp[i].tp) {
flag = 0;
break;
}
}
}
if(!flag) { /*如果有两类点重叠,无法划分*/
printf("0\n");
continue;
}
vector<int> in; /*在直线上的点*/
vector<int> a; /*A类点'o'*/
vector<int> b; /*B类点'x'*/
for(int i=1; i<=m; i++) {
for(int j=i+1; j<=m; j++) {
flag = 1;
Line l; l.a = p[i]; l.b = p[j];
a.clear(); b.clear(); in.clear();
for(int k=1; k<=m; k++) {
if(is_inline(p[i], p[j], p[k])) { /*在直线上*/
in.push_back(k);
continue;
}
if(p[k].tp == 0) {
if(a.empty()) {
a.push_back(k);
if(!b.empty()) {
/*因为只能维护是否在同一边而不能具体到是左边还是右边,所以要判断集合中的第一个点是否违背条件,样例2可以说明这一点*/
if(same_side(p[k],p[b[0]],l)) {
flag = 0;
break;
}
}
} else {
if(opposite_side(p[a[0]],p[k],l)) {
flag = 0;
break;
}
else a.push_back(k);
}
continue;
}
if(p[k].tp == 1) {
if(b.empty()) {
b.push_back(k);
if(!a.empty()) {
if(same_side(p[k],p[a[0]],l)) {
flag = 0;
break;
}
}
} else {
if(opposite_side(p[b[0]],p[k],l)) {
flag = 0;
break;
}
else b.push_back(k);
}
continue;
}
}
if(!flag) continue;
/*对直线上的点判断是否有"间隔出现"的情况*/
sort(in.begin(), in.end());
int sz = in.size();
bool change = 0;
int last = p[in[0]].tp;
for(int k=1; k<sz; k++) {
if(p[in[k]].tp != last) {
if(!change) {
last = p[in[k]].tp;
change = 1;
}
else {
flag = 0;
break;
}
}
}
if(flag) {
//printf("%d %d\n", i,j);
goto las;
}
}
}
las:
if(flag) printf("1\n");
else printf("0\n");
}
return 0;
}
UVALive 7461 Separating Pebbles (计算几何)的更多相关文章
- UVaLive 7461 Separating Pebbles (暴力)
题意:给出平面上的两类点,判断是否能画一条直线将两类点完全分割开来. 析:用暴力去枚举任意两点当作直线即可. 代码如下: #pragma comment(linker, "/STACK:10 ...
- UVALive7461 - Separating Pebbles 判断两个凸包相交
//UVALive7461 - Separating Pebbles 判断两个凸包相交 #include <bits/stdc++.h> using namespace std; #def ...
- UVALive 4428 Solar Eclipse --计算几何,圆相交
题意:平面上有一些半径为R的圆,现在要在满足不与现有圆相交的条件下放入一个圆,求这个圆能放的位置的圆心到原点的最短距离. 解法:我们将半径扩大一倍,R = 2*R,那么在每个圆上或圆外的位置都可以放圆 ...
- UVaLive 6693 Flow Game (计算几何,线段相交)
题意:给个棋盘,你可以在棋盘的边缘处放2个蓝色棋子2个黄色棋子,问连接2组同色棋子的最小代价,如果线路交叉,输-1. 析:交叉么,可以把它们看成是两条线段,然后如果相交就是不行的,但是有几种特殊情况, ...
- UVALive 7749 Convex Contour (计算几何)
题意:给定上正方形,圆,三角形,让你求出包围它的最短的路径. 析:首先,如果是这种情况 三角形 三角形 三角形 正方形(圆) 三角形 三角形 三角形 ..这一种就是直接从左边直接连到正方形(圆),也 ...
- UVALIVE 5893 计算几何+搜索
题意:很复杂的题意,我描述不清楚. 题目链接:http://acm.bnu.edu.cn/bnuoj/contest_show.php?cid=3033#problem/33526 大致是,给定一个起 ...
- UVALive 4426 Blast the Enemy! 计算几何求重心
D - Blast the Enemy! Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Subm ...
- UVALive 4818 - Largest Empty Circle on a Segment (计算几何)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- 【计算几何】【辛普森积分法】UVALive - 7076 - Highway
春节前后想了好久才在队友的讲解下想明白…… 太难讲了,我就不讲了,大概就是考虑直着走到高速上还是斜着走到高速上,然后平移直线和大圆相切,把生成的最大的“桥”和大圆并一下就行了. #include< ...
随机推荐
- JAVA文件中获取路径及WEB应用程序获取路径方法
JAVA文件中获取路径及WEB应用程序获取路径方法 1. 基本概念的理解 `绝对路径`:你应用上的文件或目录在硬盘上真正的路径,如:URL.物理路径 例如: c:/xyz/test.txt代表了tes ...
- junit浅学笔记
JUnit是一个回归测试框架(regression testing framework).Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(Wh ...
- Word 中没有Endnote工具栏的解决方法
环境:Windows XP + Word 2003 + EndNote 6 以下各方法可以依次试一下,需要重启Word后才能看到是否可行.1 视图 -- 工具栏 -- EndNote,是否打勾.2 w ...
- Android log日志
LOG是用来记录程序执行过程的机制,它既可以用于程序调试,也可以用于产品运营中的事件记录.在Android系统中,提供了简单.便利的LOG机制,开发人员可以方便地使用. androidsdk中提供了l ...
- Reactor模式,或者叫反应器模式
Reactor这个词译成汉语还真没有什么合适的,很多地方叫反应器模式,但更多好像就直接叫reactor模式了,其实我觉着叫应答者模式更好理解一些.通过了解,这个模式更像一个侍卫,一直在等待你的召唤,或 ...
- I.MX6 开启 1000Mb/s interface
/*********************************************************************** * I.MX6 开启 1000Mb/s interfa ...
- 给你一个承诺 - 玩转 AngularJS 的 Promise(转)
在谈论Promise之前我们要了解一下一些额外的知识:我们知道JavaScript语言的执行环境是“单线程”,所谓单线程,就是一次只能够执行一个任务,如果有多个任务的话就要排队,前面一个任务完成后才可 ...
- Java [Leetcode 118]Pascal's Triangle
题目描述: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5 ...
- [Everyday Mathematics]20150107
设 $f\in C^1[a,b]$, $f(a)=0$, 且存在 $\lm>0$, 使得 $$\bex |f'(x)|\leq \lm |f(x)|,\quad \forall\ x\in [a ...
- (原创)LAMP教程3-下载centos6.4
(原创)LAMP教程3-下载centos6.4 今天我要给大家讲的是安装CentOS-6.4-x86_64,是的没有错,就是64位的,因为我的机子是4G的内存,安装64位的centos是绰绰有余啊,但 ...