连线游戏Game of Lines

以后,如果不是A+B问题,我尽量每题都写,聚沙成塔

1610: [Usaco2008 Feb]Line连线游戏

Time Limit: 5 Sec   Memory Limit: 64 MB
Submit: 2080   Solved: 928
[ Submit][ Status][ Discuss]

Description

Farmer John最近发明了一个游戏,来考验自命不凡的贝茜。游戏开始的时 候,FJ会给贝茜一块画着N (2 <= N <= 200)个不重合的点的木板,其中第i个点 的横、纵坐标分别为X_i和Y_i (-1,000 <= X_i <=1,000; -1,000 <= Y_i <= 1,000)。 贝茜可以选两个点画一条过它们的直线,当且仅当平面上不存在与画出直线 平行的直线。游戏结束时贝茜的得分,就是她画出的直线的总条数。为了在游戏 中胜出,贝茜找到了你,希望你帮她计算一下最大可能得分。

Input

* 第1行: 输入1个正整数:N

 * 第2..N+1行: 第i+1行用2个用空格隔开的整数X_i、Y_i,描述了点i的坐标

Output

第1行: 输出1个整数,表示贝茜的最大得分,即她能画出的互不平行的直线数

Sample Input

4
-1 1
-2 0
0 0
1 1

Sample Output

* 第1行: 输出1个整数,表示贝茜的最大得分,即她能画出的互不平行的直线数

HINT

4 输出说明: 贝茜能画出以下4种斜率的直线:-1,0,1/3以及1。

斜率水题,直接上代码
var
n,i,j,y,x,ans,tot:longint;
flag,bl:boolean;
k:array[-1..20001]of double;
a,b:array[-1..201]of longint;
procedure qsort(l,r:longint);
var i,j:longint; mid,x:double;
begin
        i:=l;
        j:=r;
        mid:=k[(i+j)shr 1];
        repeat
                while k[i]mid do dec(j);
                if i<=j then
                        begin
                                x:=k[i];
                                k[i]:=k[j];
                                k[j]:=x;
                                inc(i);
                                dec(j);
                        end;
        until i>j;
        if il then qsort(l,j);
end;
begin
        readln(n);
        for i:=1 to n do
                begin
                        readln(a[i],b[i]);
                end;
        for i:=1 to n do
                for j:=i+1 to n do
                begin
                        if a[i]=a[j] then//横坐标相同,即x轴平行,这点要判断一下,否则除数将为0
                                begin
                                        flag:=true;
                                end
                        else if b[i]=b[j] then//纵坐标相同,这个可要可不要
                                begin
                                        bl:=true;
                                end
                        else
                                begin
                                        inc(tot);
                                        x:=a[i]-a[j];
                                        y:=b[i]-b[j];
                                        k[tot]:=y/x;
                                end;
                end;
        qsort(1,tot);//判断种类问题,一般用到快排
        ans:=1;//因为n条斜率,最多有n条不同,最少有1条不同,又只能判断n-1次,因此将ans的初值定为1
        for i:=2 to tot do
                begin
                        if k[i]-k[i-1]<>0 then
                                begin
                                        //writeln(k[i]:0:2);
                                        inc(ans);
                                end;
                end;
        if flag then inc(ans);
        if bl then inc(ans);
        writeln(ans);
end.

总结:

1、斜率等坐标问题,必须考虑除数为0的情况。

2、判断是否重复(种类问题)可用类似桶排序的方法,但对于此题,会使桶排序的数组下标为实数,因此选用快排



你可能感兴趣的:(数学,数学,数论,斜率)