9月22日 交汇的火力

题目

题目描述

   小D正在玩CS,喜欢思考的他看到无数子弹从他眼前飞过时想到了一个奇怪的问题:这么多子弹在空中飞来飞去,难道它们不会相撞吗?当然这是可能的.小D把两颗子弹轨迹相交的地方叫做”火力汇点”,显然如果让敌人站在火力汇点上那么他将受到更严重的伤害.小D想知道平面上的所有火力汇点以便对敌人造成更重的打击,但是小D数学很差,所以他找到了你,请你帮他计算出平面上所有火力汇点的坐标.小D用直线来描述子弹的轨迹,这种子弹很特别,它发射后会迸裂成两颗并沿相反方向飞行(汗!!那不是打自己),小D数学很差(已知),只会用直线的一般式表示每条直线y=kx+b.
 

输入

n
k1 b1
k2 b2
.
kn bn
第一行一个数n,表示直线数量
接下来n行,每行描述一条直线

输出

一个数,火力汇点的个数
若交点不存在请输出No Fire Point. (结尾有小点哦)

输入样例复制

2
1 0
-1 2

输出样例复制

1

说明

[数据规模] 对所有数据k,b<=maxint n<=100
 
 
分析
   我们知道,当k1==k2时就不会相交也不会平行,所以我们只需要求有多少个不同的而且不平行的线就可以了
     但问题是会存在多个交点,所以我们需要去重
     根据数学,我们可以推算出x=(k1-k2)/(b2-b1)得到 y坐标带入就可以了,然后存入数组进行判断
     注意因为涉及有小数,所以要开double
代码
 1 #include<iostream>
 2 using namespace std;
 3 int ans;
 4 double a[100001],b[100001],p[100001][3];
 5 int main ()
 6 {
 7     int n;
 8     cin>>n;
 9     double x,y;
10     int sb=0;
11     for (int i=1;i<=n;i++)
12         cin>>a[i]>>b[i];
13     for (int i=1;i<=n;i++)
14       for (int j=i+1;j<=n;j++)
15       {
16          if (a[i]==0&&a[j]==0) continue;
17            if (a[i]==a[j])
18              continue;
19            double l=a[i]-a[j];
20            double r=b[j]-b[i];
21            x=r/l;
22            y=a[i]*x+b[i];
23            int f=0;
24            for (int k=1;k<=sb;k++)
25            {
26                if (p[k][1]==x&&p[k][2]==y)
27                {
28                    f=1; break;
29                }
30            }
31            if (f==0)
32            {
33                sb++;
34               p[sb][1]=x;
35               p[sb][2]=y;
36               ans++;
37            }
38            
39       }
40     if (ans==0)
41       cout<<"No Fire Point.";
42     else
43     cout<<ans;
44 }

 

   
posted @ 2018-09-23 12:15  Melted_czj  阅读(125)  评论(0编辑  收藏  举报
body { background-color:whitesmoke; } // 修改背景颜色为半透明 #home,#sideBarMain>div,#blog-sidecolumn>div>div,.catListView{ background-color:rgba(255,255,255,0); } // 修改其他边框的颜色