UVALive 6955 Finding Lines

题意:

   问能否在给定的图中,找到足够多的点使其落在一条直线上,这些点的数量除以总数量大于等于给定的概率。


解题:

    是看了别人的做法后,才知道这么做的。随机取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;
}


你可能感兴趣的:(思维,概率,uva)