题意:
问能否在给定的图中,找到足够多的点使其落在一条直线上,这些点的数量除以总数量大于等于给定的概率。
解题:
是看了别人的做法后,才知道这么做的。随机取2个点,然后判断所有点是否落在直线上,若落在直线上的比例大于等于给定概率则停止,否则继续循环,直至10000次(貌似1000也就够了。)若循环10000次后仍未找到大于概率的情况则输出impossible。(注意特殊处理,N为1或2的情况)
总结:
感觉思维有些受限,看到那么大的n,而且给定的又是概率,应该往这方面想才对!
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <cstdlib>
#define maxn 100010
using namespace std;
int storex[maxn],storey[maxn];
int main()
{
int n,p,tmp1,tmp2,cnt,limit;
long long x1,y1,x2,y2,difx,dify,dif;
bool flag;
double poss;
srand(time(0));
while(~scanf("%d%d",&n,&p))
{
flag=false;
limit=n*p;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&storex[i],&storey[i]);
}
if(n==1||n==2)
{
printf("possible\n");
continue;
}
for(int i=1;i<=10000;i++)
{
cnt=0;
tmp1=rand()%n+1;
while(1)
{
tmp2=rand()%n+1;
if(tmp2!=tmp1)break;
}
x1=storex[tmp1];
y1=storey[tmp1];
x2=storex[tmp2];
y2=storey[tmp2];
difx=x1-x2;
dify=y1-y2;
dif=y2*x1-y1*x2;
for(int j=1;j<=n;j++)
{
if((storey[j]*difx)==(dify*storex[j]+dif))
cnt++;
}
if(100*cnt>=limit)
{
flag=true;
break;
}
}
if(flag)printf("possible\n");
else printf("impossible\n");
}
return 0;
}