UVALive 6955 Finding Lines(随机化优化)题解

题意:问你是否有一条直线满足这条直线上的点个数与总个数之比不小于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

UVALive 6955 Finding Lines(随机化优化)题解的相关文章

Finding Lines

Finding Lines 题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4967 概率 在听题解前毫无头绪,题解帮我打开了新世界的大门: 随机取一个点在答案直线(如果存在这个直线)上的概率是p%, 那么随机取到两个点构成的直线就是答案直线的概率是p%*p%: 也就是说,随机取到两个点构成的直线不是答案直线的概率为

随机算法 - HNU 13348 Finding Lines

Finding Lines Problem's Link: http://acm.hnu.cn/online/?action=problem&type=show&id=13348&courseid=0 Mean: 给你平面上1e5个点,让你判断是否可以找到一条直线,使得p%的点都在这条直线上. analyse: 经典的随机算法题. 每次随机出两个点,然后对n个点进行判断,看是否有p%的点在这条直线上. 关于随机算法正确性的证明: 每次随机一个点,这个点在直线上的概率是p,p最小为2

POJ 1088 滑雪 记忆化优化题解

本题有人写是DP,不过和DP还是有点差别的,应该主要是记忆化 Momoization 算法. 思路就是递归,然后在递归的过程把计算的结果记录起来,以便后面使用. 很经典的搜索题目,这种方法很多题目考到的. 关键还是如何把代码写清晰工整了,O(∩_∩)O~. #include <stdio.h> const int MAX_N = 101; int R, C; int arr[MAX_N][MAX_N]; int tbl[MAX_N][MAX_N]; inline int max(int a,

UVALive 4976 Defense Lines ——(LIS变形)

题意:给出序列,能够从这序列中删去连续的一段,问剩下的序列中的最长的严格上升子串的长度是多少. 这题颇有点LIS的味道.因为具体做法就是维护一个单调的集合,然后xjbg一下即可.具体的见代码吧: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 const int N = 2e5 + 5; 6 7 int T,n,top,back; 8 i

快速排序的优化(一)随机化快速排序

这周研究快速排序优化策略,首先是利用随机化对快速排序进行优化. 众所周知,之前的基础快速排序算法,其效率一个关键点就在与划分元素的选取,由于之前一直选取的是第一个元素,所以当遇到特殊输入,比如太大或者太小,就会造成区间划分极度不合理. 引入随机化,就是在每一次划分的时候随机选取一个元素作为关键字,用它来进行划分.由于每一次划分都是随机选取,所以每一次都选到不好的元素概率低,可以作为一个优化的方向. 和之前的基础快速排序主要区别有两个 1.首先是partition部分 利用rand产生随机数  ,

18.10.16 队测

T1 : 求给定集合有多少个非空子集可以分割成两个集合,使得它们的和相等. 其中:\(n\leq20~,~a[i]\leq1e8\) 题目可以转化成:给每个数前添加一个系数\(p\in[-1,1]\),使得和为0的方案数. 由于\(n\)比较小,所以可以考虑爆搜.朴素的爆搜可以枚举每个数不选,第一个集合,第二个集合,复杂度\(O(3^n)\) . 然后发现根据套路,可以想到折半搜索\((meet~ in~ the ~middle)\) 先爆搜前十个的状态和\(sum\),然后爆搜后十个进行匹配,

NOI2005瑰丽华尔兹

1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 893  Solved: 508[Submit][Status] Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是很少有几个人知道,世界上最伟大的钢琴家一生都漂泊在大海上,他的名字叫丹尼•布德曼•T.D.•柠檬•1900,朋友们都叫他1900. 1900在20世纪

3404: [Usaco2009 Open]Cow Digit Game又见数字游戏

3404: [Usaco2009 Open]Cow Digit Game又见数字游戏 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 72  Solved: 48[Submit][Status][Discuss] Description 贝茜和约翰在玩一个数字游戏.贝茜需要你帮助她. 游戏一共进行了G(1≤G≤100)场.第i场游戏开始于一个正整数Ni(l≤Ni≤1,000,000).游 戏规则是这样的:双方轮流操作,将当前的数字减去一个数,这个数可

开篇——给磁盘文件排序

问题描述: 输入:是一个包含n个正整数的文件,每个数都小于n,n<10^7如果在输入文件中出现任何重复整数就是致命错误 输出:按升序排列的输入的整数列表 约束:最多有1MB 的内存可用,有充足的磁盘存储空间,运行时间最多几分钟,10秒即可不比优化 题解: 内存只有1MB,即最多能存1024*1024*8位二进制数,一个int型占32字节,每个字节是8位 采用位图存储集合,每个二进制位表示该位置所表示的数字存在与否,采用位运算提高程序运行速度 代码如下: #include<iostream>