2036. Intersect Until You're Sick of It

题目连接:

http://acm.timus.ru/problem.aspx?space=1&num=2036

Description

Ural contests usually contain a lot of geometry problems. Many participants do not conceal their discontent with such disbalance. Still, we have decided not to break the tradition and give you an unbalanced contest. Let’s start!

Consider an iterative process for a set of points on a plane. Every iteration consists of three steps:

Draw a line through every pair of different points.

Find all intersections of all pairs of different non-parallel lines.

Merge the initial set of points with the set of intersection points and go to step one.

After each iteration, the number of points either increases or stays the same.

You are given a set of points. Iterations repeat while the number of points increases. How many points will be in the set after the end of this iterative process?

Input

The first line contains an integer n (1 ≤ n ≤ 100000). Further input describes n different points. For every point, you are given a pair of integer coordinates whose absolute value does not exceed 108.

Output

If the process is infinite, print “oo” (two lowercase Latin letters ‘o’), otherwise print the number of points in the set after the end of the process.

Sample Input

4

0 0

0 1

1 0

1 1

Sample Output

5

Hint

题意

给你n个点,然后进行下列操作:

1.两两点连线

2.找到所有不平行直线所构成的交点

3.把所有找到的点和原来的点合并,如果点数增加,再进行1操作;否则break

输出最后点的数量。

可能是无限多。

题解:

无限多的情况很多,我们来考虑特殊情况,即有解的:

显然所有点都是在一条直线上,这个答案是n

显然如果只有一个点不在直线上,这个答案也是n

有两个点不在直线上,那么答案可能是n,也有可能是n+1.

基本上情况就这些了,讨论一下,然后求解即可。

数据:

Anti-WA #51:

4

0 0

2 0

1 1

1 2

Answer: oo

Anti-WA #52:

4

0 0

1 2

2 2

3 0

Answer: oo

代码

#include <bits/stdc++.h>

using namespace std;
const int N=100010;
const int inf=1e9; struct POINT
{
long long x;
long long y;
POINT(long long a=0, long long b=0) { x=a; y=b;} //constructor
bool operator<(const POINT &A)const{
if(A.x==x)return A.y<y;
return A.x<x;
}
};
long long multiply(POINT sp,POINT ep,POINT op)
{
return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
}
long long multiply(POINT A,POINT B,POINT C,POINT D)
{
long long x1 = A.x-B.x;
long long y1 = A.y-B.y;
long long x2 = C.x-D.x;
long long y2 = C.y-D.y;
return x1*y2-x2*y1;
}
POINT P[N];
int n; int solve(POINT st)
{
vector<POINT> ans,ret;
if(st.x==0&&st.y==0)
{
return inf;
}
for(int i=1;i<=n;i++)
{
if(multiply(P[i],st,P[1])!=0) ans.push_back(P[i]);else ret.push_back(P[i]);
}
if(ans.size()<=1)
{
return n;
}
else
{
for(int i=2;i<ans.size();i++)
if(multiply(ans[0],ans[1],ans[i])!=0) return inf;
for(int i=0;i<ret.size();i++)
if(multiply(ret[i],ans[1],ans[0])==0)
return n;
if(ans.size()>2)
{
return inf;
}
else
{
long long t1=multiply(ans[0],st,P[1]),t2=multiply(ans[1],st,P[1]);
if(t1>0&&t2>0||t1<0&&t2<0)
{
return inf;
}
else
{
POINT pp;
int flag=1,f1=1,f2=1;
for(int i=0;i<ret.size();i++)
{
if(multiply(ret[i],ans[1],ans[0])<0) f1=0;
if(multiply(ret[i],ans[1],ans[0])>0) f2=0;
}
if(f1||f2) flag=0;
return n+flag;
}
}
}
} long long X(POINT A,POINT B){
return A.x*B.y-A.y*B.x;
}
long long sq(long long A){
return A*A;
}
long long dis(POINT A,POINT B){
return sq(A.x-B.x)+sq(A.y-B.y);
}
bool ok4(){
long long tmp = multiply(P[1],P[2],P[3],P[4]);
if(tmp!=0)return 0;
tmp = multiply(P[1],P[2],P[3]);
if(tmp==0)return 0;
long long dis1 = dis(P[1],P[2]);
long long dis2 = dis(P[3],P[4]);
if(dis1!=dis2)return 0;
return 1;
}
bool ok14(){
long long tmp = multiply(P[1],P[2],P[3]);
if(tmp==0)return 1;
long long dis1 = dis(P[1],P[2]);
long long dis2 = dis(P[3],P[4]);
if(dis1==dis2)return 1;
return 0;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%I64d%I64d",&P[i].x,&P[i].y);
}
for(int i=2;i<=n;i++)
P[i].x-=P[1].x,P[i].y-=P[1].y;
P[1].x=P[1].y=0;
int tmp=inf;
if(n<=3)
{
printf("%d\n",n);
return 0;
}
if(n==4){
sort(P+1,P+1+n);
do{
if(ok4()){
printf("5\n");
return 0;
}
}while(next_permutation(P+1,P+1+n));
sort(P+1,P+1+n);
do{
if(ok14()){
printf("4\n");
return 0;
}
}while(next_permutation(P+1,P+1+n));
printf("oo\n");
return 0;
}
if(n<=5)
{
for(int o=2;o<=n;o++)
{
tmp=min(tmp,solve(P[o]));
}
}
else
{
int flag=0;
POINT stt;
stt.x=stt.y=0;
for(int i=2;i<=6;i++)
{
for(int j=i+1;j<=6;j++)
{
for(int k=j+1;k<=6;k++)
if(multiply(P[i],P[j],P[1])==0&&multiply(P[i],P[k],P[1])==0)
{
stt=P[i];
flag=1;
break;
}
if(flag) break;
}
if(flag) break;
}
tmp=solve(stt);
}
if(tmp==inf) printf("oo\n");else printf("%d\n",tmp);
return 0;
}

Ural 2036. Intersect Until You're Sick of It 计算几何的更多相关文章

  1. URAL 2036 Intersect Until You're Sick of It 形成点的个数 next_permutation()函数

    A - Intersect Until You're Sick of It Time Limit:500MS     Memory Limit:65536KB     64bit IO Format: ...

  2. URAL 2025. Line Fighting (math)

    2025. Line Fighting Time limit: 1.0 second Memory limit: 64 MB Boxing, karate, sambo- The audience i ...

  3. LINQ to SQL语句(8)之Concat/Union/Intersect/Except

    适用场景:对两个集合的处理,例如追加.合并.取相同项.相交项等等. Concat(连接) 说明:连接不同的集合,不会自动过滤相同项:延迟. 1.简单形式: var q = ( from c in db ...

  4. 【oracle】union、union all、intersect、minus 的用法及区别

    一.union与union all 首先建两个view create or replace view test_view_1 as as c from dual union as c from dua ...

  5. oracle之集合操作函数---minus、union、intersect

    集合操作符专门用于合并多条select语句的结果,包括:UNION,UNION ALL,INTERSECT,MINUS.当使用集合操作函数时,需保证数据集的字段数据类型和数目一致. 使用集合操作符需要 ...

  6. LINQ的Intersect方法

    找到两个集合中交集部分: source code: IEnumerable<int> a = new List<int>{ { }, { }, { } }; IEnumerab ...

  7. Linq连接查询之左连接、右连接、内连接、全连接、交叉连接、Union合并、Concat连接、Intersect相交、Except与非查询

    内连接查询 内连接与SqL中inner join一样,即找出两个序列的交集 Model1Container model = new Model1Container(); //内连接 var query ...

  8. List之Union(),Intersect(),Except()

    http://www.cnblogs.com/qinpengming/archive/2012/12/03/2800202.html List之Union(),Intersect(),Except() ...

  9. Sql中的并(UNION)、交(INTERSECT)、差(minus)、除去(EXCEPT)详解

    UNION 查询选修了180101号或180102号课程或二者都选修了的学生学号.课程号和成绩. (SELECT  学号, 课程号, 成绩 FROM   学习 WHERE   课程号='180101' ...

随机推荐

  1. Linux学习6-套接字

    套接字 1.什么是套接字? 套接字(socket)是一种通信机制,凭借这种机制,客户/服务器系统的开发工作既可以在本地单机上进行,也可以跨网络进行. 2.套接字应用程序是如何通过套接字来维持一个连接的 ...

  2. 仿QQ聊天图文混排流程图【适用于XMPP】

      图文混排流程图.graffle4.8 KB   下面附上图片素材: 表情.zip692.5 KB     下面是字符串与图片的详细对应关系:                 "[呲牙]& ...

  3. continue和break区别

    break 语句用于跳出循环. continue 用于跳过循环中的一个迭代. 一个迭代,就是一次循环,continue终止本次循环,继续下一次循环: break,循环终止不再循环.

  4. Oracle 基本操作符

    1.一般操作符 (1)!= 不等于 select empno,ename,job from scott.emp where job!='manager' (2)^= 不等于 select empno, ...

  5. Linux awk工具简单学习记录

    awk是一个文本分析工具,它把文件逐行读入,以特定符号将每行切分(默认空格为分隔符),切开的部分再进行各种分析处理. awk其名称得自于它的创始人Alfred Aho .Peter Weinberge ...

  6. Jenkins的安装及使用(二)

    介绍两个方面:编译本地项目和拉取git代码并编译 在这之前,先要进行一个配置. 一.编译本地项目 开始添加任务,任务类型选择自由风格: 点击项目进入详情,源码管理选择无 在构建的地方选择项目,然后注意 ...

  7. 【网络编程】使用getnameinfo()/getaddrinfo()/InetPton()

    1.简要 从前用的网络编程函数现在又做了一定的改动,报了这么3个错误. error C4996: 'inet_ntoa': Use inet_ntop() or InetNtop() instead ...

  8. echo变量失败,提示:ECHO 处于关闭状态

    检查变量值,变量值为空就会提示关闭

  9. Tomcat优化步骤【转】

    一.Tomcat的缺省是多少,怎么修改 Tomcat的缺省端口号是8080.修改Tomcat端口号:1.找到Tomcat目录下的conf文件夹2.进入conf文件夹里面找到server.xml文件3. ...

  10. 【坐在马桶上看算法】算法4:队列——解密QQ号

            新学期开始了,小哈是小哼的新同桌(小哈是个小美女哦~),小哼向小哈询问QQ号,小哈当然不会直接告诉小哼啦,原因嘛你懂的.所以小哈给了小哼一串加密过的数字,同时小哈也告诉了小哼解密规则. ...