Gym - 101482F Finding Lines

这题做法很简单,随机选两个不相同的点,那就有(1/p)^2的概率这两个点在这条可能的直线上,唯一要注意的是,你随机数不能用rand,会被卡,就是这个卡了我们一个多小时,用mt19937就可以了

题目链接

#include
using namespace std;
#define ll long long
const int N = 1e5+10;
struct Point{
	ll x,y;
	Point(){}
	Point(ll _x,ll _y){
		x = _x;
		y = _y;
	}
	ll cross(Point b,Point c){
		return (b.x-x)*(c.y-y)-(b.y-y)*(c.x-x);
	}
}q[N];
typedef std::mt19937  Random_mt19937;
Random_mt19937  rnd(time(0));
ll rd(ll l,ll r)
{
    return (rnd()%(r-l+1)+l);
}
int main(){
	ll n,p;
	srand(time(0));
	scanf("%lld%lld",&n,&p);
	for(int i = 1; i <= n; i++){
		cin>>q[i].x>>q[i].y;
	}
	if(n<=2){
		printf("possible\n");
		return 0;
	}
	for(ll i = 1; i <= 1000; i++){
		ll ans = 2;
		ll a = rd(1,n),b =rd(1,n);
		while(b==a) a = rd(1,n),b =rd(1,n);
		for(ll j = 1; j <= n; j++){
			if(j!=a&&j!=b){
				if((q[a].y-q[b].y)*(q[a].x-q[j].x)==(q[a].y-q[j].y)*(q[a].x-q[b].x))
				ans++;
			}
			//printf("j=%d a=%d b=%d\n",j,a,b);
		}
		if(ans*100ll>=n*p) {
			printf("possible\n");
			return 0;
		}
	}
	printf("impossible\n");
}
/*
5
55
0 0
10 10
10 0
0 10
3 3

9 69
13 999
628 423
942 302
231 848
725 389
603 944
246 683
517 848
778 76

5
45
0 0
10 10
10 0
0 10
3 4
*/

 

你可能感兴趣的:(cf,随机,1000篇)