登录—专业IT笔试面试备考平台_牛客网
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
假设平面上有 nnn 颗 fumo 星,编号分别为 1,2,…,n1,2,\dots,n1,2,…,n。求这样的直线的数量:直线经过这 nnn 颗 fumo 星中至少 222 个序号不同的 fumo 星。
输入描述:
首先输入一行一个整数 n(1≤n≤103)n(1\leq n \leq 10^{3})n(1≤n≤103),表示 fumo 星的数量。接下来输入 n 行,每行 2 个整数 xi,yi(−109≤xi≤109,−109≤yi≤109)代表序号为 i 的 fumo 星的横坐标与纵坐标。
输出描述:
如果有无数条满足的直线,输出 "inf"(不含引号);否则输出一行一个整数,表示直线的数量。
示例1
输入
2 1 1 2 2
输出
1
示例2
输入
4 0 0 1 1 2 2 3 3
输出
1
示例3
输入
2 1 1 1 1
输出
inf
解析:
看完题目,先别急着做题,先看数据范围,再看时间限制。发现时间限制很大,我们可以使用n^2级别的时间复杂度来处理这个问题。
最简单的方法就是将所有的点都遍历一遍,每次遍历的时候枚举所有可能与它形成直线的点。同时使用gcd将斜率化成最小分数,使用map或其他容器存储每个点形成的所有直线。
根据初中知识,确定一条直线只需要一个点和一个斜率即可。
因此可以这样存一条直线:map<点,map<斜率,是否存在>>mp;
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
#include<sstream>
#include<deque>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<double, double> PDD;
const int INF = 0x3f3f3f3f;
const LL Mod = 1e9;
const int N = 1e3 + 10, M = 4e5 + 10, P = 110;
int n;
struct node {int x, y;
}node[N];
map<int, map<pair<int,int>, int>>mp;
map<PII, int>p;int gcd(int a, int b) {if (b == 0)return a;return gcd(b, a % b);
}int main() {cin >> n;int flg = 0;for (int i = 1; i <= n; i++) {scanf("%d%d", &node[i].x, &node[i].y);if (p.count({ node[i].x,node[i].y })) {flg = 1;}p[{node[i].x,node[i].y}]=1;}int ans = 0;if (flg) {cout << "inf" << endl;}else {for (int i = 1; i <= n; i++) {for (int j = 1; j < i; j++) {int x = node[i].x - node[j].x, y = node[i].y - node[j].y;int g = gcd(x, y);x /= g;y /= g;if (!mp[j].count({x,y})) {ans++;}mp[j][{x,y}] = 1;mp[i][{x, y}] = 1;}}cout << ans << endl;}return 0;
}
再提供一个队友写的代码,效率更高:
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
#include<sstream>
#include<deque>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
using namespace std;
const int N = 1e4 + 10;
#define LL long long
tuple<LL, LL, LL> o;
set<tuple<LL, LL, LL> > p;
LL a[N], b[N];
LL n;
LL gcd(LL x, LL y)
{if (!y) return x;return gcd(y, x % y);
}
int main()
{cin >> n;for (int i = 1; i <= n; i++) cin >> a[i] >> b[i];if (n == 1){cout << 0 << endl;return 0;}int flag = 0;for (int i = 1; i <= n; i++){for (int j = i + 1; j <= n; j++){if (a[i] == a[j] && b[i] == b[j]){flag = 1;break;}LL x = b[j] - b[i], y = a[j] - a[i], z = y * b[i] - x * a[i];LL gc = gcd(gcd(x, y), z);if (!gc) p.insert({ x,y,z });else {x = x / gc;y /= gc;z /= gc;p.insert({ x,y,z });}}if (flag)break;}if (flag){cout << "inf" << endl;return 0;}cout << p.size() << endl;return 0;}