交汇的火力

Description

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

Input

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

Output

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

Sample Input

2
1 0
-1 2

Sample Output

1

题解

如果两条直线有交点那么就可以得到k1x+b1=k2x+b2如果x有解那么就表示有交点。存储下每个x和y最后排序判重。

代码

var
  n,nm:longint;
  k,b:array [0..101] of longint;
  a:array [0..10001,1..2] of real;
procedure qsort(l,r:longint);
var
  i,j:longint;
  mid1,mid2:real;
begin
  if l>r then exit;
  i:=l; j:=r;
  mid1:=a[(l+r) div 2,1];
  mid2:=a[(l+r) div 2,2];
  repeat
    while (a[i,1]<mid1) or (a[i,1]=mid1) and (a[i,2]<mid2) do inc(i);
    while (a[j,1]>mid1) or (a[i,1]=mid1) and (a[i,2]<mid2)do dec(j);
    if i<=j then
      begin
        a[0]:=a[i]; a[i]:=a[j]; a[j]:=a[0];
        inc(i); dec(j);
      end;
  until i>j;
  qsort(i,r);
  qsort(l,j);
end;

procedure init;
var
  i,j,kx,bx:longint;
begin
  readln(n);
  for i:=1 to n do
    readln(k[i],b[i]);
  for i:=1 to n-1 do
    for j:=i+1 to n do
      begin
        kx:=k[i]-k[j];
        if kx=0 then continue;
        bx:=b[j]-b[i];
        inc(nm);
        a[nm,1]:=bx/kx;
        a[nm,2]:=(k[i]*a[nm,1])+b[i];
      end;
end;

procedure main;
var
  i,mn:longint;
begin
  mn:=nm;
  for i:=2 to nm do
    if (a[i,1]=a[i-1,1]) and( a[i,2]=a[i-1,2]) then dec(mn);
  if mn=0 then writeln('No Fire Point.')
               else writeln(mn);
end;

begin
  init;
  qsort(1,nm);
  main;
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值