题意:问你是否有一条直线满足这条直线上的点个数与总个数之比不小于p
思路:解法太暴力了,直接随机取两个数,如果能满足条件就输出可以,否则继续随机直到达到300次。证明一下为什么可以随机化,题目给出可能有P >=20的点在线上,假设最惨的情况P = 20,有100个点,所以我们选一次选不到这条直线的概率为 (80 * 79)/(100 * 99),简单点我们记做0.64,那么两次我们找不到这条线的概率为0.64*.0.64……所以我们随机300次,这样选不到这条线的概率就很小很小了,除非RP不行啊。
代码:
#include<ctime> #include<cmath> #include<cstdio> #include<iostream> #include<algorithm> #define ll long long #define ull unsigned long long using namespace std; const int maxn = 100000 + 10; const int seed = 131; const int MOD = 100013; const int INF = 0x3f3f3f3f; struct node{ int x, y; }p[maxn]; bool judge(int u, int v,int i){ int x1 = p[u].x - p[i].x, x2 = p[v].x - p[i].x; int y1 = p[u].y - p[i].y, y2 = p[v].y - p[i].y; return y1 * x2 == y2 * x1; } int main(){ int n, per; while(~scanf("%d%d", &n, &per)){ per = (int)ceil((double)per / 100 * n); for(int i = 0; i < n; i++){ scanf("%d%d", &p[i].x, &p[i].y); } if(n <= 2){ printf("possible\n"); continue; } srand(time(0)); int Time = 0; bool flag = false; while(Time <= 300){ int cnt = 2; int u = rand() % n; int v = rand() % n; while(v == u) v = rand() % n; for(int i = 0; i < n; i++){ if(i == v || i == u) continue; if(judge(u, v, i)) cnt++; if(cnt >= per){ flag = true; break; } } if(flag) break; Time++; } if(flag) printf("possible\n"); else printf("impossible\n"); } return 0; }
原文地址:https://www.cnblogs.com/KirinSB/p/9530552.html
时间: 2024-10-12 06:32:20