poj 1118 2606解题报告

题目描述:

1118:飞行员一次性沿直线想飞跃尽可能多的点,输入n为位置个数(最大700),n为0时退出,后面两个一组为坐标

2606:猎人一次击杀尽可能多的兔子,首次输入个数(最大200),随后两个一组为位置坐标

(两题一样,只是1118要求多次输入n,2606没有)


算法分析:

暴力搜索,确立一条直线,其余点代入实验。确立方法是三点式  (yi-yk)*(xj-xk)=(yj-yk)*(xi-xk)(i、j、k共线)


程序代码:

#include <stdio.h>

#define MAX 700

int main(int argc, char *argv[])
{
	int n, i, j, k, count = 0, temp = 0;
	int x[MAX], y[MAX];

	while (1)
	{
		scanf("%d", &n);
		if (n == 0)
		      break;
		for ( i = 0; i < n; i++)
		      scanf("%d%d", &x[i], &y[i]);
		
		count = 0;
		for ( i = 0; i < n; i++)
		      for ( j = i+1; j < n; j++)
		      {
				temp = 2;
				for ( k = j+1; k < n; k++)
				      if ((y[i]-y[k])*(x[j]-x[k]) == (y[j]-y[k])*(x[i]-x[k]))
					    temp++;
				if (temp > count)
				      count = temp;
		      }
		printf("%d\n", count);
	}
	return 0;
}

(这个是1118,2606去掉while循环,并将MAX值改为200,去掉if(n == 0)即可)



错误版本及分析:

这两道是水题,但开始竟然WA了好几次,后来反思,原因如下:

开始直接反应用斜截式y = kx + b,如果斜率不存在用x = ky + b;

但是首先k可能是分数,用int存,不精确,必然错,若用double存,在比较点是否满足条件时又会都变成double,浮点数原则上不能比较精确大小,比较也是确定1e-10之类的范围内比,所以此法否了,换思路,用三点式可以完全避免这些问题.

错误代码如下:

#include <stdio.h>

#define MAX 700

int main(int argc, char *argv[])
{
	int n, i, j, k, b, l, count = 0, temp = 0;
	int x[MAX], y[MAX];

	while (1)
	{
		scanf("%d", &n);
		if (n == 0)
		      break;
		for ( i = 0; i < n; i++)
		      scanf("%d%d", &x[i], &y[i]);
		count = 0;
		for ( i = 0; i < n; i++)
		      for ( j = i+1; j < n-i; j++)
		      {
			      temp = 0;
			      if (x[i]-x[j] != 0)
			      {
				      k = (y[i] - y[j]) / (x[i] - x[j]);
				      b = k*y[i] - x[i];
				      for ( l = 0; l < n; l++)
				      {
					      if (x[l] == y[l]*k + b)
						    temp++;
				      }
			      }
			      else if (y[i]-y[j] != 0)
			      {
				      k = (x[i] - x[j]) / (y[i] - y[j]);
				      b = k*x[i] -y[i];
				      for ( l = 0; l < n; l++)
				      {
					      if (y[l] == x[l]*k + b)
						    temp++;
				      }
			      }
			      else
				    break;

			      if (temp > count)			
				    count = temp;

		      }
		printf("%d\n", count);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值