题目描述
小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
.
.
.
.
.
分析
求出两两之间一次函数交点的坐标
同一坐标上可能会有多个一次函数的交点,称为集合
答案就是集合的个数
PS:记得去重
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n,k[101],b[101];
double a[10001][3];
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d%d",&k[i],&b[i]);
int tj=0,ans=0;
for (int i=1;i<=n-1;i++)
for (int j=i+1;j<=n;j++)
{
if (k[i]==k[j]) continue;
int p=b[j]-b[i],q=k[i]-k[j];
double x=(double) p/q;
tj++;
a[tj][1]=x;
a[tj][2]=k[i]*x+b[i];
}
if (tj==0)
{
printf("No Fire Point.");
return 0;
} else ans=1;
double w;
for (int i=1;i<=tj-1;i++)
for (int j=1;j<=tj;j++)
if (a[i][1]>a[j][1]||a[i][1]==a[j][1]&&a[i][2]>a[j][2])
{
w=a[i][1];a[i][1]=a[j][1];a[j][1]=w;
w=a[i][2];a[i][2]=a[j][2];a[j][2]=w;
}
for (int i=2;i<=tj;i++)
if (a[i][1]!=a[i-1][1]||a[i][1]==a[i-1][1]&&a[i][2]!=a[i-1][2]) ans++;
printf("%d",ans);
return 0;
}