Tải bản đầy đủ (.docx) (5 trang)

ứng dụng của thuật toán tìm diện tích đa giác

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (82.16 KB, 5 trang )

ỨNG DỤNG THUẬT TOÁN TÌM DIỆN TÍCH ĐA GIÁC
ĐỂ LẬP TRÌNH GIẢI MỘT SỐ BÀI TOÁN VỀ HÌNH HỌC
Thuật toán hiệu quả tìm diện tích đa giác đã được nhiều tác giả nêu
ra. Tuy nhiên trong bài viết này tôi chỉ xin nêu ra một số bài toán mà nếu
ứng dụng thuật toán tìm diện tích đa giác để giải chúng sẽ rất hiệu quả.
Trước hết, ta sẽ nhắc lại thuật toán này.
Bài toán: Tính diện tích đa giác (lồi hoặc lõm và không tự cắt) gồm n đỉnh A
[1], A[2], , A[n] (n>2).
Thuật toán: Ta có thể giải bài toán này bằng cách chia đa giác thành n - 2
tam giác rồi tính tổng diện tích của các tam giác ấy. Tuy nhiên phương
pháp này phức tạp, ta làm cách khác như sau: chia đa giác thành các hình
thang bằng cách chiếu các cạnh xuống trục hoành (hoặc trục tung). Hình
thang được xác định bởi cạnh A[i]A[i+1] có diện tích là Abs(S) với :
S = (A[i].x - A [i+1].x).(A[i].y + A[i+1].y) /2
Sau khi gán đỉnh A[n+1] = A[1], ta tính diện tích toàn phần của đa
giác như sau:
S: = 0;
For i: =1 to n do
S := S + (A[i].x - A [i+1].x).(A[i].y + A[i+1].y);
S: = (1/2) * Abs(S);
Sau đây là một số ví dụ áp dụng thuật toán vừa trình bày.
Bài 1. Kiểm tra tính lồi lõm của một đa giác.
Trong mặt phẳng toạ độ có n điểm có toạ độ tương ứng là (x
1
, y
1
), (x
2
,
y
2


) , , (x
n
, y
n
). Biết rằng n điểm đã cho theo thứ tự tạo thành các đỉnh của
một đa giác không tự cắt. Yêu cầu: hãy kiểm tra đa giác lồi hay lõm.
Dữ liệu vào ghi trong file DAGIAC.INP: dòng đầu ghi một số n (n>2), n
dòng tiếp theo, trên dòng thứ i ghi hai số thực theo thứ tự là hoành độ và
tung độ của đỉnh thứ i-1 của đa giác.
Dữ liệu ra ghi vào file DAGIAC.OUT gồm một số 0 hoặc 1, ghi 0 nếu đa
giác lõm và ghi 1 nếu đa giác lồi.
Thuật toán: Gọi diện tích của đa giác là S
0
. Ta sẽ so sánh S
0
với các S
i
,
trong đó S
i
là diện tích của đa giác thu được từ đa giác ban đầu sau khi bỏ
đi đỉnh thứ i (i=1, 2, , n). Nếu ∃ i sao cho S
i
> S
0
thì đa giác đã cho lõm
(tại đỉnh thứ i), ngược lại thì đa giác đã cho lồi.
Toàn văn chương trình như dưới đây:
{Kiem tra mot da giac loi hay lom}
type

diem=record
x,y:real;
end;
var a:array [1 100] of diem;
n,vt:integer;
s0,s1:real;
procedure init;
var f:text;i:byte;
begin
assign(f,'dagiac.inp');
reset(f);
readln(f,n);
{while not eof(f) do}
for i:= 1 to n do
begin
read(f,a[i].x);
read(f,a[i].y);
end;
close(f);
a[n+1]:=a[1];
{Tinh dien tich da giac}
s0:=0;
for i:=1 to n do
s0:=s0+(a[i+1].x-a[i].x)*(a[i+1].y+a[i].y);
s0:=abs(s0)/2
end;
Procedure Inkq(i:byte);
var f:text;
begin
assign(f,'dagiac.out');

rewrite(f);
write(f,i);
close(f);
end;
Procedure resolve;
var b:array [1 50] of diem;
i,j,k:byte;
Begin
for i:=1 to n do
begin
for j:=1 to i-1 do b[j]:=a[j];
for j:=i+1 to n+1 do b[j-1]:=a[j];
s1:=0;
for j:=1 to n-1 do
s1:=s1+(b[j+1].x-b[j].x)*(b[j+1].y+b[j].y);
s1:=abs(s1)/2;
if s1>s0 then
begin
inkq(0);
halt
end;
end;
inkq(1);
End;
begin
init;
resolve;
end.
Bài 2. Chia đa giác (mô phỏng đề thi HS giỏi quốc gia lớp 12, bảng B, năm
1999-2000).

Trong mặt phẳng toạ độ có n điểm có toạ độ tương ứng là (x
1
, y
1
), (x
2
,
y
2
) , , (x
n
, y
n
). Biết rằng n điểm đã cho theo thứ tự tạo thành các đỉnh của
một đa giác không tự cắt. Yêu cầu: hãy chia đa giác đã cho thành hai đa
giác bởi một cạnh nối hai đỉnh không kề nhau sao cho diện tích của chúng
chênh lệch nhau ít nhất.
Dữ liệu vào ghi trong file DAGIAC.INP: dòng đầu ghi một số n (n>3), n
dòng tiếp theo, trên dòng thứ i ghi hai số thực theo thứ tự là hoành độ và
tung độ của đỉnh thứ i-1 của đa giác.
Dữ liệu ra ghi vào file DAGIAC.OUT gồm hai số nguyên dương chỉ số thứ
tự của hai đỉnh được nối sao cho thoả mãn điều kiện đầu bài.
Thuật toán: Ta đưa ra thuật toán rất đơn giản như sau: thử tìm mọi cách
chia và ghi nhận lại cách chia tốt nhất. Dễ thấy độ phức tạp của thuật toán
trong trường hợp này là O(n
3
).
Toàn văn chương trình như dưới đây:
Program vd;
type

diem=record
x,y:real;
end;
var a:array [1 100] of diem;
n,vt1,vt2:integer;
s0,s1,del:real;
procedure init;
var f:text;i:byte;
begin
assign(f,'dagiac.inp');
reset(f);
readln(f,n);
for i:= 1 to n do
begin
read(f,a[i].x);
read(f,a[i].y);
end;
close(f);
a[n+1]:=a[1];
s0:=0;
for i:=1 to n do
s0:=s0+(a[i+1].x-a[i].x)*(a[i+1].y+a[i].y);
s0:=abs(s0)/2;
del:=s0;
end;
Procedure resolve;
var b:array [1 50] of diem;
i,j,k,h:byte;
f:text;
Begin

for i:=1 to n-2 do
begin
for h:=i+2 to n-1 do
begin
k:=0;
for j:= i to h do
begin
inc(k);
b[k]:=a[j];
end;
b[k+1]:=b[1];
s1:=0;
for j:=1 to k do
s1:=s1+(b[j+1].x-b[j].x)*(b[j+1].y+b[j].y);
s1:=abs(s1)/2;
if del>abs(2*s1-s0) then
begin
vt1:=i;
vt2:=j;
del:=abs(2*s1-s0);
end;
end;
end;
assign(f,'dagiac.out');
rewrite(f);
write(f,vt1,' ',vt2);
close(f);
End;
begin
init;

resolve;
end.
Bài tập. Tứ giác bao n điểm (mô phỏng đề thi olympic Sinh viên khối
không chuyên 1999).
Cho n điểm có toạ độ (x
i
, y
i
), i = 1, 2 , , n với n > 4. Lập chương trình tìm
4 điểm sao cho 4 điểm này tạo thành một tứ giác có diện tích lớn nhất.

×