Nguồn đề bài: http://vn.spoj.com/problems/BALLGMVN/
1. Đề bài BALLGMVN spoj
Trong một hội thi Ballgame, ban tổ chức chuẩn bị một bàn lớn. Trên mặt bàn có n bi xanh đánh số từ 1 đến n và n bi đỏ đánh số từ n + 1 đến 2n. Mỗi trận đấu, các vận động viên sẽ chơi luân phiên nhau. Đến lượt chơi của mình, Hùng cần tìm 3 bi mà vị trí của chúng là thằng hàng hanu và sao cho trong số đó có hai bi đỏ và 1 bi xanh (khi đó ăn được một bi đỏ), hoặc là có hai bi xanh và 1 bi đỏ (khi đó được ăn 1 bi xanh).
Yêu cầu
Cho biết tọa độ trên mặt phẳng tọa độ Đề-các của vị trí và màu của các bi hiện tại trên bàn, bạn hãy giúp Hùng chọn 3 bi để chơi.
Input
- Dòng đầu ghi số nguên dương n.
- Dòng thứ i trong số n dòng tiếp theo ghi hai số nguyên là hoành độ và tung độ trên mặt phẳng tọa độ Đề-các của vị trí đặt bi xanh với chỉ sô i.
- Dòng thứ i trong số n dòng cuối cùng ghi hai số nguyên là hoàng độ và tung độ trên mặt phẳng tọa độ Đề-các của vị trí đặt bi đỏ với chỉ số n + i.
- Hoàng độ và tung độ không vượt quá 10^6, vị trí các bi là đôi một phân biệt.
Giới hạn
- 30% số test có n <= 2;
- 30% số test khác có n <= 100.
- 40% số test còn lại có n <= 1000.
Output
Ghi ra 3 chỉ số của các viên bi mà Hùng cần chọn, nếu không thể chọn được 3 bi nào, ghi ra -1. Nếu có nhiều đáp án, ghi ra một đáp án bất kì.
Example
Input:
3
1 1
2 2
4 9
3 3
6 20
8 100
Output:
1 2 4
2. Hướng dẫn giải BALLGMVN spoj – VOI 2014
Với mỗi điểm[i] từ 1–>N:
- Xem điểm[i] là gốc tọa độ, nên dựng được xNew[j]=x[j]-x[i] và yNew[j]=y[j]-y[i] với 1<=j<=N.
- Sort các điểm theo giá trị x/y.
- Các điểm có cùng giá trị chính là các điểm trên cùng một đường thẳng.
ĐPT: O(N^2 log N)
Với cách trên các bạn sẽ gặp chút rắc rối ở viên bi màu. vậy các bạn có thể chọn i làm gốc tọa độ của 1 tập, còn tập kia chỉ cần chọn 2 điểm có tỉ số x/y như hướng dẫn ở trên bằng nhau là được. Như vậy, các bạn có thể chia thành 2 tập viên bị màu xanh và viên bi màu đỏ. và làm tương tự như cách ở trên 2 lần.
3. Code tham khảo BALLGMVN spoj – VOI 2014
const fi='';
nmax=3000;
type data=longint;
var
f:text;
idd,xd,yd,idx,xx,yx,idnew:array[0..nmax+1] of data;
xynew:array[0..nmax+1] of real;
n:data;
procedure docfile;
var i,j:data;
begin
assign(f,fi); reset(f);
readln(f,n);
for i:=1 to n do
begin
readln(f,xx[i],yx[i]);
idx[i]:=i;
end;
for i:=1 to n do
begin
readln(f,xd[i],yd[i]);
idd[i]:=n+i;
end;
close(f);
end;
procedure Swap(var a,b:data);
var z:data;
begin
z:=a;
a:=b;
b:=z;
end;
procedure sort(l,r: longint);
var
i,j: longint;
x,y:real;
begin
i:=l;
j:=r;
x:=xynew[(l+r) div 2];
repeat
while xynew[i]<x do inc(i);
while x<xynew[j] do dec(j);
if not(i>j) then
begin
y:=xynew[i];
xynew[i]:=xynew[j];
xynew[j]:=y;
swap(idnew[i],idnew[j]);
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
procedure xuli;
var i,j,u,v:data;
begin
// N vien bi xanh lam goc
for i:=1 to n do
begin
for j:=1 to n do
begin
u:=xx[i]-xd[j];
v:=yx[i]-yd[j];
idnew[j]:=idd[j];
if v=0 then
xynew[j]:=high(data)
else
xynew[j]:=u/v;
end;
sort(1,n);
for j:=1 to n-1 do
if xynew[j]=xynew[j+1] then
begin
writeln(idx[i],' ',idnew[j],' ',idnew[j+1]);
readln;
halt;
end;
end;
// N vien bi do lam goc
for i:=1 to n do
begin
for j:=1 to n do
begin
u:=xd[i]-xx[j];
v:=yd[i]-yx[j];
idnew[j]:=idx[j];
if v=0 then
xynew[j]:=high(data)
else
xynew[j]:=u/v;
end;
sort(1,n);
for j:=1 to n-1 do
if xynew[j]=xynew[j+1] then
begin
writeln(idd[i],' ',idnew[j],' ',idnew[j+1]);
readln;
halt;
end;
end;
writeln(-1);
end;
begin
docfile;
xuli;
end.