交汇的火力

题目描述

小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;
}
原文地址:https://www.cnblogs.com/YYC-0304/p/10292847.html