标签:
(Uva 6955可以直接随机,湖大OJ 13348 要优化)
题意:给出 n个点的坐标, 一个 百分数p, 求是否有一条直线上有 n * p /100个点…
随机化算法,但也要优化下……(TLE, WA到底…)
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<map> #include<set> #include<vector> #include<queue> #include<stack> //#include<bits/std c++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; const LL MOD = 1e7 + 7; const LL maxn = 1e5 + 131; int gcd(int a,int b) { return b == 0 ? a : gcd(b, a % b); } unsigned int Rand() { static unsigned seed = 233; return seed = seed * 1000007 + 1;} struct Line { long long a,b,c; Line() {} Line(int a1,int b1,int a2,int b2) { int g = gcd(abs(a1 - a2),abs(b1 - b2)); if(a1 - a2 < 0) g = -g; a = -(b1-b2)/g; this->b = (a1-a2) / g; this->c = a*a1 + b*b1; } bool operator < (Line s) const { return (a < s.a || (a == s.a && (b < s.b || (b == s.b && c < s.c))));} }; map<Line,int> L; map<Line,int>::iterator it; int X[100031], Y[100031]; int main() { int n,p; scanf("%d%d",&n,&p); L.clear(); if(n == 1) { printf("possible\n"); return 0;} int limit = n * p; for(int i = 0; i < n; ++i) scanf("%d%d",&X[i],&Y[i]); for(int t = 0; t < 1000; ++t) { //先随机处理去重 + 统计次数 int a = Rand() % n, b = Rand() % n; while(a == b) b = Rand() % n; L[Line(X[a],Y[a],X[b],Y[b])]++; } for(it = L.begin(); it != L.end(); ++it) { if(it->second < 20) continue;//随机1000次,在线上的点应该要出现一定次数 1/25 * 1000, 20保险,然而30 40 WA了... int num = 0; //简直拼人品....... long long a = it->first.a, b = it->first.b, c = it->first.c; for(int i = 0; i < n; ++i) { if(a*X[i] + b*Y[i] == c) { num++; if(num * 100 >= limit) { printf("possible\n"); return 0; } } } } printf("impossible\n"); return 0; }
标签:
原文地址:http://www.cnblogs.com/aoxuets/p/4697306.html