F - Finding Lines Gym - 101482F(随机化)

Annabel and Richard like to invent new games and play against each other. One day Annabel has a new game for Richard. In this game there is a game master and a player. The game master draws n points on a piece of paper. The task for the player is to find a straight line, such that at least p percent of the points lie exactly on that line. Richard and Annabel have very good tools for measurement and drawing. Therefore they can check whether a point lies exactly on a line or not. If the player can find such a line then the player wins. Otherwise the game master wins the game.
There is just one problem. The game master can draw the points in a way such that it is not possible at all to draw a suitable line. They need an independent mechanism to check whether there even exists a line containing at least p percent of the points, i.e., ⌈n · p/100⌉ points. Now it is up to you to help them and write a program to solve this task.
Input
The input consists of:
• one line with one integer n (1 ≤ n ≤ 105), the number of points the game master has drawn;
• one line with one integer p (20 ≤ p ≤ 100), the percentage of points which need to lie on the line;
• n lines each with two integers x and y (0 ≤ x, y ≤ 109), the coordinates of a point. No two points will coincide.
Output
Output one line containing either “possible” if it is possible to find a suitable line or “impossible” otherwise.
(0,10)
(0,0)
(3,3)
(10,10)
(10,0)
(0,10) (10,10)
(3,4)
(0,0) (10,0)
(b) Sample input 2: No line with at least 3 points exists.
(a) Sample input 1: A line with (at least) 3 of the points exists.
Figure F.1: Illustration of the sample inputs
NWERC 2014 Problem F: Finding Lines 11
Sample Input 1
Sample Output 1
5
55 00 10 10 10 0 0 10 33
possible
Sample Input 2
Sample Output 2
5
45 00 10 10 10 0 0 10 34
impossible

题意:
一些点,求是否存在一个直线包含至少num个点
思路:
随机化,随机这些点,然后以前两个点作为这条直线,随机1000次看是否存在合理答案。

证明:
假设直线存在,那么直线上两个点被随机到的概率是 p 2 / 10000 p^2/10000 p2/10000
不被随机到的概率是 1 − p 2 / 10000 1-p^2/10000 1p2/10000
那么随机1000次不被随机到的概率是 ( 1 − p 2 / 10000 ) 1000 (1-p^2/10000)^{1000} (1p2/10000)1000
这个值很小了,所以基本正确。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef long long ll;

const int maxn = 5e5 + 7;

struct Point {
    double x,y;
}a[maxn];

double Cross(double x1,double y1,double x2,double y2) {
    return x1 * y2 - x2 * y1;
}

int main() {
    int n;
    double p;
    scanf("%d%lf",&n,&p);
    int num = ceil((double)n * p / 100);
    for(int i = 1;i <= n;i++) {
        scanf("%lf%lf",&a[i].x,&a[i].y);
    }
    if(n <= 2) {
        printf("possible\n");
        return 0;
    }
    srand(time(NULL));
    for(int i = 1;i <= 1000;i++) {
        int ans = 2;
        random_shuffle(a + 1, a + 1 + n);
        for(int j = 3;j <= n;j++) {
            if(Cross(a[1].x - a[2].x,a[1].y - a[2].y,a[1].x - a[j].x,a[1].y - a[j].y) == 0) ans++;
        }
        if(ans >= num) {
            printf("possible\n");
            return 0;
        }
    }
    printf("impossible\n");
    return 0;
}

你可能感兴趣的:(#,gym,#,随机化)