您的位置:首页 > 大数据 > 人工智能

2016 Multi-University Training Contest 2 1005 Eureka

2016-07-22 21:01 381 查看
题目链接:点击打开链接

题目大意:给你n个点问不在同一直线上的点有多少种取法(至少两个)

解题思路:这题思路其实很明确,但是由于重点的问题很麻烦,最后决定保存重点数量但是不压缩,枚举前两个点,二分找同k的点数;另外对于一条用n个点的直线,他的可能性有2^n-n-1种,但是为了不重复计算,我们只算当前这个点对结果的贡献即(2^n-n-1)-(2^(n-1)-(n-1)-1)=2^(n-1)-1;这样计算就可以处理重复计算情况,时间复杂度大概是n*n*log(n)

代码:

#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<ctime>
#include "cstdio"
#include "string"
#include "string.h"
#include "map"
#include "vector"
using namespace std;
const int mod = 1000000007;
const int maxn = 1010;
struct Node
{
long long x, y;
bool friend operator<(Node a,Node b)
{
if (a.x == b.x)
return a.y < b.y;
else
return a.x < b.x;
}
bool friend operator>(Node a, Node b)
{
if (a.x == b.x)
return a.y > b.y;
else
return a.x > b.x;
}
bool friend operator==(Node a, Node b)
{
return a.x == b.x&&a.y == b.y;
}
bool friend operator<=(Node a, Node b)
{
return a < b || a == b;
}
bool friend operator>=(Node a, Node b)
{
return a > b || a == b;
}
}node[maxn],temp[maxn];
long long pow2[maxn];
map<Node, int>mp;
int now;
bool cmp(Node a, Node b)
{
Node c = node[now];
return (b.x - c.x)*(a.y - c.y) < (a.x - c.x)*(b.y - c.y);
}
bool online(Node a, Node b, Node c) {
long long dx1 = b.x - a.x;
long long dy1 = b.y - a.y;
long long dx2 = c.x - a.x;
long long dy2 = c.y - a.y;
return dx2 * dy1 == dx1 * dy2;
}
int main()
{
pow2[0] = 1;
for (int i = 1;i <= 1000;i++)
pow2[i] = (pow2[i - 1] * 2) % mod;
int T, n;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
mp.clear();
long long ans = 0;
for (int i = 1;i <= n;i++)
{
scanf("%lld %lld", &node[i].x, &node[i].y);
mp[node[i]]++;
}
sort(node + 1, node + n + 1);
for (int i = 1;i <= n;i++)
{
i += mp[node[i]] - 1;
now = i;
memcpy(temp, node, sizeof(temp));
sort(temp + i + 1, temp + n + 1, cmp);
for (int j = i + 1;j <= n;)
{
int k = j + 1;
if (!online(node[i], temp[j], temp[min(j + 3, n)]))
while (k <= n&&online(node[i], temp[j], temp[k]))
k++;
else
k = upper_bound(temp + j, temp + n + 1, temp[j], cmp) - temp;
ans = (ans + (pow2[k - j] - 1)*(pow2[mp[node[i]]]-1)) % mod;
j = k;
}
ans = (ans + pow2[mp[node[i]]] - mp[node[i]] - 1) % mod;
}
printf("%lld\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息