题目1548:平面上的点:直线穿过最多点(不应该这样AC吗?)

题目1548:平面上的点

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:775

解决:81

题目描述:

给定平面上的n个点,任意做一条直线,求至多能有几个点恰好落在直线上。

输入:

包含多组测试数据,每组测试数据由一个整数n(0<=n<=100)开始,代表平面上点的个数。
接下去n行每行给出一个点的坐标(x,y),x、y的绝对值均小于等于100。

输出:

对于每组测试数据,输出一个整数,表示至多能有几个点恰好落在直线上。

样例输入:
2
0 0
1 1
4
0 0
1 1
2 2 
3 6
样例输出:
2
3
来源:
2014年王道论坛研究生机试练习赛(一)
这道题很是纠结,问题在于有重复的点,即(x1,y1)和(x2,y2),其中x1=x2,y1=y2。但是,网上的AC答案只考虑有两个点是重复的,难道三个点以上重复不存在吗?是数据太弱了~~
网上的AC代码是这样的:
#include <stdio.h>
const int maxn = 102;
struct Node{
    int x;
    int y;
};
int n, i;
Node nodes[maxn];
 
int max(int a, int b){
    return a > b ? a : b;
}
int main(){
    while(scanf("%d",&n) != EOF){
        for(i = 0; i < n; i++){
            scanf("%d %d",&nodes[i].x,&nodes[i].y);
        }
        if(n == 0 || n == 1 || n == 2){
            printf("%d\n",n);
            continue;
        }
        int maxNum = 0;
        for(i = 0; i < n; i++){
            int x1 = nodes[i].x;
            int y1 = nodes[i].y;
            for(int j = i+1; j < n; j++){
                int x2 = nodes[j].x;
                int y2 = nodes[j].y;
                int tempNum = 2;
                if (x2 == x1 && y2 == y1) {
                    tempNum = 3;
                    j++;
                }
                x2 = nodes[j].x;
                y2 = nodes[j].y;
                for (int k = j+1; k < n; k++) {
                    int x3 = nodes[k].x;
                    int y3 = nodes[k].y;
                    int num1 = (y3 - y1)*(x2 - x1);
                    int num2 = (y2 - y1)*(x3 - x1);
                    if (num1 == num2) {
                        tempNum++;
                    }
                }
                maxNum = max(tempNum, maxNum);
            }
        }
        printf("%d\n",maxNum);
    }
    return 0;
}
/**************************************************************
    Problem: 1548
    User: wangzhenqing
    Language: C++
    Result: Accepted
    Time:30 ms
    Memory:1020 kb
****************************************************************/

很明显,使用if()排除重复点的情况一次,
if (x2 == x1 && y2 == y1) {  
                    tempNum = 3;  
                    j++;  
                }  
而我的代码是这样的:
#include<stdio.h>  
#include<string.h>  
#include<stdlib.h>  
#include<math.h>  
int n,max;  
double a[105][5];  
int pan(int x,int y,int p)  
{  
    if(fabs((a[x][1]-a[y][1])*(a[p][0]-a[y][0])-(a[p][1]-a[y][1])*(a[x][0]-a[y][0]))<1E-5)  
        return 1;  
    else 
        return 0;  
}  
int main()  
{  
    int i,j,k;  
    int tem;  
    while(scanf("%d",&n)!=EOF)  
    {  
        for(i=0;i<n;i++)  
        {  
            scanf("%lf%lf",&a[i][0],&a[i][1]);  
        }  
        max=0;  
        if(n == 0 || n == 1 || n == 2)  
        {    
            printf("%d\n",n);  
            continue;    
        }  
        for(i=0;i<n;i++)  
        {  
            for(j=i+1;j<n;j++)  
            {  
                tem=2;  
                while(j<n&&fabs(a[i][0]-a[j][0])<1E-5 && fabs(a[i][1]-a[j][1])<1E-5)   
                {    
                    tem++;    
                    j++;    
                }
                if(j==n)
                    tem--;
                /*if (fabs(a[i][0]-a[j][0])<1E-5 && fabs(a[i][1]-a[j][1])<1E-5) {   
                    tem = 3;   
                    j++;   
                }  */ 
                for(k=j+1;k<n;k++)  
                {  
                    if(pan(i,j,k))  
                    {  
                        tem++;  
                    }  
                }  
                max=(max<tem)?tem:max;  
            }  
        }  
        printf("%d\n",max);  
    }  
    return 0;  
}  
/**************************************************************
    Problem: 1548
    User: smileyk
    Language: C++
    Result: Accepted
    Time:30 ms
    Memory:1024 kb
****************************************************************/


改了好久,原来是边界问题没考虑,囧~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值