9月22日 交汇的火力
题目
题目描述
小D正在玩CS,喜欢思考的他看到无数子弹从他眼前飞过时想到了一个奇怪的问题:这么多子弹在空中飞来飞去,难道它们不会相撞吗?当然这是可能的.小D把两颗子弹轨迹相交的地方叫做”火力汇点”,显然如果让敌人站在火力汇点上那么他将受到更严重的伤害.小D想知道平面上的所有火力汇点以便对敌人造成更重的打击,但是小D数学很差,所以他找到了你,请你帮他计算出平面上所有火力汇点的坐标.小D用直线来描述子弹的轨迹,这种子弹很特别,它发射后会迸裂成两颗并沿相反方向飞行(汗!!那不是打自己),小D数学很差(已知),只会用直线的一般式表示每条直线y=kx+b.
输入
n
k1 b1
k2 b2
.
kn bn
第一行一个数n,表示直线数量
接下来n行,每行描述一条直线
k1 b1
k2 b2
.
kn bn
第一行一个数n,表示直线数量
接下来n行,每行描述一条直线
输出
一个数,火力汇点的个数
若交点不存在请输出No Fire Point. (结尾有小点哦)
若交点不存在请输出No Fire Point. (结尾有小点哦)
输入样例复制
2
1 0
-1 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 }
为何要逼自己长大,去闯不该闯的荒唐