SỞ GD & ĐT VĨNH PHÚC
TRƯỜNG PT DTNT CẤP 23 VĨNH PHÚC
BÁO CÁO KẾT QUẢ
SÁNG KIẾN KINH NGHIỆM
Tên sáng kiến kinh nghiệm: “Một số phương pháp
hình học cơ bản để giải quyết các bài tốn Tin
học”
Tác giả sáng kiến: Nguyễn Đăng Hiệp
Mã sáng kiến: 04.62.01
Vĩnh Phúc, năm 2020
MỤC LỤC
Trang
Trang
...........................................................................................2
1. Lời giới thiệu
................................................................................................1
2. Tên sáng kiến:
..............................................................................................1
“Một số phương pháp hình học cơ bản để giải quyết các bài tốn
...................
Tin học” 1
3. Tác giả sáng kiến:
.........................................................................................1
5. Lĩnh vực áp dụng sáng kiến:
............................................................................1
7. Mô tả bản chất của sáng ..........................................................................
kiến:
2
7.1. Về nội dung của sáng kiến:
............................................................................2
7.1.1. Thực trạng của vấn đề mà sáng kiến cần giải
......................................
quyết.
2
7.1.2. Các giải pháp:
.........................................................................................2
Ví dụ............................................................................................................15
DAGIAC.INP.................................................................................................15
DAGIAC.OUT................................................................................................15
* Phương pháp 1: Dựa vào định nghĩa đa....................................................
giác lồi
15
Bài 5: Cờ vây
................................................................................................37
Bài 6: Rệp điện .........................................................................................
tử
38
Bài 7: Cắt gạch lát nền
...................................................................................39
7.2. Về khả năng áp dụng của sáng
..............................................................
kiến:
40
8. Những thông tin cần được bảo mật:........................................................
không
40
9. Các điều kiện cần thiết để áp dụng sáng
....................................................
kiến:
41
10. Đánh giá lợi ích thu được của sáng
...........................................................
kiến
41
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
BÁO CÁO KẾT QUẢ
NGHIÊN CỨU, ỨNG DỤNG SÁNG KIẾN
1. Lời giới thiệu
Các bài tốn tin rất đa dạng và phong phú và thể loại, tuy nhiên để áp dụng
và giải quyết các bài tốn này u cầu học sinh phải nắm vững về kiến thức
tốn học. Trong chương trình phổ thơng, mơn Tin học được đưa vào giảng dạy
chính khố từ năm học 2006 2007. Lớp 11 các em sẽ được tiếp cận với ngơn
ngữ lập trình Pascal, một trong những ngơn ngữ lập trình được chọn giảng dạy
khơng chỉ ở các trường THPT mà cịn được đưa vào giảng dạy ở các trường Đại
học. Ngơn ngữ lập trình Pascal cịn được chọn là ngơn ngữ lập trình trong các kỳ
thi OLYMPIC Tin học Quốc tế.
Đối với người lập trình, kiến thức tối thiểu là biết được cách tổ chức cấu
trúc dữ liệu và nêu được thuật tốn để giải bài tốn, phát hiện bài tốn và áp
dụng các phương pháp giải các dạng tốn đều phải qua một q trình hình thành
và tích luỹ. Xin nêu “Một số phương pháp hình học cơ bản để giải quyết các
bài tốn Tin học” trong chương trình phổ thơng và nêu một số bài tốn nâng cao.
2. Tên sáng kiến:
“Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học”
3. Tác giả sáng kiến:
Họ và tên: Nguyễn Đăng Hiệp
Địa chỉ: Trường Phổ Thơng Dân Tộc Nội Trú Cấp 23 Vĩnh Phúc
Số điện thoại: 0975.486.964 E_mail:
4. Chủ đầu tư tạo ra sáng kiến: Nguyễn Đăng Hiệp
5. Lĩnh vực áp dụng sáng kiến:
Đề tài giúp học sinh tổng hợp và phát triển thuật tốn sao cho gần gũi với tư duy
của học sinh phổ thơng.
1
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
Đây cũng là một vấn đề mới vì: Muốn hiển thị được một điểm ảnh hay hoạt
động của con chuột máy tính đúng toạ độ, các lập trình viên đã phải lập trình và
căn đúng toạ độ cho con chuột… Như vậy các phương pháp giải quyết bài tốn
này đã được nghiên cứu từ rất lâu, các bài tốn này được các nhà nghiên cứu về
tốn học và lý thuyết Tin học đưa ra. Các vấn đề đưa ra là giúp học sinh sự tổng
hợp và phát triển thuật tốn gần gũi với tư duy của mình
6. Ngày sáng kiến được áp dụng lần đầu hoặc áp dụng thử
Sáng kiến được áp dụng với 100 học sinh khối 11 trong trường bắt đầu
từ học kỳ 1 năm học 2019 2020
7. Mơ tả bản chất của sáng kiến:
7.1. Về nội dung của sáng kiến:
7.1.1. Thực trạng của vấn đề mà sáng kiến cần giải quyết.
Như chúng ta đã biết lập trình trong Tin học là một phần học rất khó, địi hỏi
nhiều đến sự phát triển tư duy để tìm tìm thuật tốn và địi hỏi học sinh phải
nắm vững kiến thức về mặt tốn học nên đa số học sinh khơng say mê với mơn
học này. Vì vậy vai trị của giáo viên là rất quan trọng, làm thế nào để cho học
sinh có hứng thú, khơng khí lớp học thoải mái. Giáo viên phải có phương pháp
truyền đạt lơi cuốn học sinh thơng qua gợi mở, thuyết minh, giải quyết vấn
đề… Nhưng vẫn đảm bảo thời gian, và nội dung cơ bản của giờ học.
Song do tình trạng chung hiện nay học sinh đa số mất gốc về mặt tốn
học, cơ sở vật chất để phục vụ giảng dạy cịn thiếu vì vậy ảnh hưởng rất
nhiều đến khả năng tiếp thu và sự say mê của học sinh khi học Tin học. Cho nên
hiệu quả giờ học khơng cao.
7.1.2. Các giải pháp:
Để học sinh đạt được mục đích, u cầu của chuẩn kiến thức, tơi đã tìm tịi,
nghiên cứu, hướng dẫn học sinh thảo luận một số phương pháp hình học để
2
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
giải quyết bài tốn. Giúp các em xây dựng được một số thuật tốn điển hình ở
dạng đơn giản và nâng cao. Tiết học trở nên sinh động hơn và giáo viên khơng
đóng vai trị là người xây dựng lý luận mà học sinh là người chủ động để giải
quyết các vấn đề.
Để giờ dạy đạt hiệu quả cao và tạo hứng thú học tập của học sinh tơi đã chuẩn
bị các slide (bằng phần mềm Microsoft Power Point) để trình chiếu và sử dụng
các phần mềm để mơ phỏng các thuật tốn.
Sau đây là một số phương pháp hình học cơ bản để giải quyết các bài tốn
Tin học thơng qua các bài tốn điển hình dưới đây:
1 Vị trí tương đối của điểm so với đường thẳng và đoạn thẳng
Bài tốn 1: Tìm vị trí tương đối của điểm M(x0; yo) so với đường thẳng đi qua 2
điểm A(x1; y1) và B(x2; y2) (với x1 x2)
Phương trình đường thẳng qua A, B là (yy1)(x2 – x1) = (y2y1)(xx1)
hay là: (y2y1)*x (x2x1)*y + y1*x2 –x1* y2 = 0.
+) Nếu (y2y1)*x0 (x2x1)*y0 + y1*x2 –x1* y2 > 0 thì điểm M nằm phía trên cao
hơn đường thẳng AB.
+) Nếu (y2y1)*x0 (x2x1)*y0 + y1*x2 x1* y2 < 0 thì điểm M nằm phía dưới thấp
hơn đường thẳng AB.
Bài tốn 2: Điểm M(x0,yo) có thuộc đoạn thẳng nối 2 điểm A(x1,y1) và B(x2,y2)
hay khơng (với x1 x2)
Điểm M(x0,yo) thuộc đoạn thẳng nối 2 điểm A(x1,y1) và B(x2,y2) (với x1
x2) nếu thoả mãn: (y2y1)*x0 (x2x1)*y0 + y1*x2 x1* y2 = 0 và Min(x1, x2) x0
Max(x1, x2)
2 Giao của các Đoạn thẳng
3
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
Bài tốn 3: Cho 2 đoạn thẳng AB và CD, toạ độ các đầu mút là A(x 1,y1),
B(x2,y2), C(x3,y3) và D(x4,y4). Hãy xét xem hai đoạn thẳng này có giao nhau
khơng.
a) Cách 1:
Tìm giao điểm của 2 đường thẳng AB và CD bằng cách giải hệ gồm 2
phương trình:
(y2y1)*x (x2x1)*y + y1*x2 x1* y2= 0 (1)
(y4y3)*x (x4x3)*y + y3*x4 x3* y4 = 0 (2)
Sau đó kiểm tra xem giao điểm có thuộc 2 đoạn thẳng AB và CD hay khơng
Tìm giao điểm (nếu có) của hai đường thẳng trong mặt phẳng tọa độ có
phương trình lần lượt là a1x + b1y = c1 và a2x + b2y = c2.
Bài tốn này có thể dễ dàng giải được bằng việc sử dụng phương pháp đã biết ở
phổ thơng. Cụ thể:
D: = a1*b2 a2*b1; Dx : = c1*b2 c2*b1; Dy: = a1*c2 a2*c1;
If D < > 0 then Writeln (' x = ', Dx/D : 4:2, 'y = ', Dy/D: 4:2)
else If (Dx = 0) and (Dy = 0) then Writeln (' H ai đường thẳng trùng nhau’)
b) Cách 2:
Trước hết xét bài tốn phụ: Trên mặt phẳng toạ độ cho tam giác ABC, đi trên
cạnh từ A đến B rồi đến C theo chiều nào (ngược chiều kim đồng hồ hay thuận
chiều kim đồng hồ) với giả thiết khơng có cạnh nào song song trục tung.
Ta thấy khơng mất ý nghĩa của bài tốn khi ta quay tồn bộ tam giác một cách
tuỳ ý. Vì vậy đầu tiên ta giả sử A là đỉnh có hồnh độ bé nhất (x2 > x1,x3 > x1) thì
hệ số góc đường thẳng AB là: k1= (y2 y1)/ (x2 x1)
hệ số góc đường thẳng AC là: k2= (y3 y1)/ (x3 – x1)
Ký hiệu dy1 = (y2 – y1); dx1 = (x2 x1) > 0
dy2 = (y3 – y1); dx2 = (x3 –x1) > 0
4
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
Do đó đi trên cạnh từ A đến B rồi đến C theo chiều ngược chiều kim đồng hồ
khi k2 > k1 hay là dy2* dx1 > dx2 *dy1 ( mã hố là chiều +1 )
Ngược lại đi trên cạnh từ A đến B rồi đến C theo chiều thuận chiều kim đồng
hồ khi k2 < k1 hay là dy2* dx1 < dx2 *dy1 ( mã hố là chiều 1 )
Trong trường hợp A, B, C thằng hàng thì dy2* dx1 = dx2 *dy1; khi đó ta phải xem
xét chi tiết hơn: điểm nào nằm giữa 2 điểm cịn lại?
+ Nếu B, A, C thì dx1*dx2 < 0 hoặc dy1*dy2 < 0, góc quay từ AB tới AC là 180
độ, vậy quy ước đi từ A đến B rồi đến C là thuận chiều kim đồng hồ (mã hố là
chiều 1)
+ Nếu A, B, C thì qua A kẻ đường thẳng nằm ngang At, gọi hình chiếu của B, C
xuống At lần lượt là H, K thì AB2 =AH2 + BH2 < AK2 + CK2 nên dx12 +dy12 < dx22
+ dy22, ta quy ước chiều đi từ A đến B rồi đến C là ngược chiều kim đồng hồ
(mã hố là chiều +1).
+ Nếu B, C, A thì quy ước (mã hố là chiều 0)
Uses crt;
const max = 10;
type diem = record x,y: integer end;
doanthang = record p1,p2: diem end;
var l: array[1..2] of doanthang;
procedure nhap;
var i: integer;
begin
for i:=1 to 2 do
begin
write('toado(x1,y1)(x2,y2)doanthu',i,': ');
readln(l[i].p1.x,l[i].p1.y,l[i].p2.x,l[i].p2.y);
end;
5
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
end;
function chieu(p1,p2,p3: diem): integer;
var dx1,dx2,dy1,dy2: integer;
begin
dx1: = p2.xp1.x;
dy1: = p2.yp1.y;
dx2: = p3.xp1.x;
dy2: = p3.yp1.y;
if dx1*dy2>dy1*dx2 then chieu: = 1;
if dx1*dy2
if dx1*dy2=dy1*dx2 then
begin
if (dx1*dx2<0)or(dy1*dy2<0) then chieu: = 1
else
if (dx1*dx1+dy1*dy1>=dx2*dx2+dy2*dy2) then chieu: = 0
else cq: = 1;
end;
end;
function giaonhau(l1,l2: doanthang): boolean;
begin
giaonhau: = (chieu(l1.p1,l1.p2,l2.p1)*chieu(l1.p1,l1.p2,l2.p2)<=0)
and (chieu(l2.p1,l2.p2,l1.p1)*chieu(l2.p1,l2.p2,l1.p2)<=0);
end;
BEGIN
clrscr;
nhap;
6
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
if giaonhau(l[1],l[2]) then writeln('giao nhau')
else writeln('khong giao nhau ');
readln;
END.
Có được điều đó là vì đoạn thẳng AB giao với đoạn thẳng CD khi và chỉ
khi đi theo ABC ngược chiều với ABD và đi theo CDA ngược chiều với CDB
3 Vi trí của Điểm so với Đa giác
Bài tốn 4: Cho đa giác gồm N đỉnh d[1],d[2],...,d[n] và điểm M. Hãy xác
định vị trí tương đối của M với miền trong của đa giác (M nằm ngồi hay nằm
trong đa giác)
Thuật tốn: Kẻ đoạn thẳng MN song song trục hồnh sao cho hồnh độ của N
lớn hơn hồnh độ max của các hồnh độ đỉnh đa giác. Xét giao các cạnh của đa
giác với đoạn thẳng MN. Số giao điểm là lẻ thì M trong đa giác, chẵn thì M
ngồi đa giác
Có một trở ngại là gặp những trường hợp: Đỉnh d[i+1] của cạnh nằm trên
đoạn thẳng MN, thì cạnh d[i]d[i+1] và cạnh d[i+1]d[i+2] đều giao với đoạn
MN, hoặc cạnh d[i]d[i+1] nằm trên đoạn thẳng MN thì cả 3 cạnh d[i1]d[i],
d[i]d[i+1], d[i+1]d[i+2] đều giao với MN nên xử lý như chương trình sau:
Ngồi ra ta cũng có thể giải bài tốn này bằng cách chia đa giác thành n2
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
dài dịng, 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 hồnh (hình vẽ).
Hình thang được xác lập bởi cạnh A [i] A[i+1]có diện tích là Abs (S) với
1
S= * ( A[i ]* x − A[i + 1]* x ) * ( A[i ]* y + A[i + 1]* y )
2
7
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
1
Vậy S = S + ( A[i]* x − A[i + 1]* x ) * ( A[i ]* y + A[i + 1]* y ) ; S = Abs ( S )
2
Sau khi gán đỉnh A[n+1]:=A[1] ta tính diện tích tồn phần của đa giác như sau:
S: = 0;
For i: =1 to N do S: = (1/2) * Abs(S);
Chú ý :
1. Hồn tồn tương tự ta có thể tìm diện tích của đa giác bằng cách chiếu các
cạnh xuống trục tung.
2. Nếu thay bước gán S: = (1/2) * abs (S) bởi S: = S/2 thì dấu của S là dương hay
âm sẽ cho ta biết chiều đánh số của các đỉnh theo thứ tự từ 1, 2,.... N là ngược
hay xuôi chiều kim đồng hồ.
Uses crt;
const max = 100;
fi = 'dagiac.inp';
type diem = record x,y: integer; end;
doanthang = record p1,p2: diem; end;
8
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
var l: array[1..2] of doanthang;
d: array[0..max+2] of diem;
m: diem;
n: byte;
maxx: integer;
function chieu(p1,p2,p3: diem): integer;
{Xac dinh chieu di tu p1>p2>p3}
var dx1,dx2,dy1,dy2: integer;
begin
dx1: = p2.xp1.x;
dy1: = p2.yp1.y;
dx2: = p3.xp1.x;
dy2: = p3.yp1.y;
if dx1*dy2>dy1*dx2 then chieu: = 1;
if dx1*dy2
if dx1*dy2=dy1*dx2 then
begin
if (dx1*dx2<0) or (dy1*dy2<0) then chieu: = 1
else
if (dx1*dx1+dy1*dy1>=dx2*dx2+dy2*dy2) then chieu: = 0
else chieu: = 1;
end;
end;
function giaonhau(l1,l2: doanthang): boolean;
begin
giaonhau: = (chieu(l1.p1,l1.p2,l2.p1)*chieu(l1.p1,l1.p2,l2.p2)<=0)
9
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
and (chieu(l2.p1,l2.p2,l1.p1)*chieu(l2.p1,l2.p2,l1.p2)<=0);
end;
procedure nhap;
var i: integer;
f: text;
begin
assign(f,fi);
reset(f);
readln(f,n);
maxx: = maxint;
for i:=1 to n do
begin
readln(f,d[i].x,d[i].y);
if d[i].x>maxx then maxx: = d[i].x;
end;
readln(f,m.x,m.y);
close(f);
end;
function thuoc(p: diem;lp: doanthang): boolean;
var a,b,c: real;
function min2(a,b: real): real;
begin
if a
end;
function max2(a,b: real): real;
begin
10
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
if a>b then max2: = a else max2: = b;
end;
begin
a: = lp.p2.ylp.p1.y;
b: = lp.p1.xlp.p2.x;
c: = lp.p1.y*lp.p2.xlp.p1.x*lp.p2.y;
if (a*p.x+b*p.y+c=0) and (min2(lp.p1.x,lp.p2.x)<=p.x)
and (max2(lp.p1.x,lp.p2.x)>=p.x) then thuoc: = true
else thuoc: = false;
end;
function trong(p: diem): boolean;
var dem,i,j: integer;
lt,lp: doanthang;
begin
dem: = 0;
d[0]: = d[n];
d[n+1]: = d[1];
d[n+2]: = d[2];
lt.p1: = p;
lt.p2.y: = p.y;
lt.p2.x: = maxx+1;
for i:=1 to n do
begin
lp.p1: = d[i];
lp.p2: = d[i+1];
if thuoc(p,lp) then
begin
11
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
trong: = true;
exit;
end;
if giaonhau(lp,lt) and (lp.p1.y<>p.y) and (lp.p2.y<>p.y) then inc(dem);
if giaonhau(lp,lt) and ((lp.p1.y=p.y) and (lp.p2.y=p.y))
and ((d[i1].yd[i].y)*(d[i+2].yd[i].y)<0)
then inc(dem);
if giaonhau(lp,lt) and (d[i+1].y=p.y)
and ((d[i].yp.y)*(d[i+2].yp.y)<0)
then inc(dem);
end;
trong: = ((dem mod 2)=1);
end;
BEGIN
clrscr;nhap;
if trong(m) then writeln('diem m nam trong da giac ')
else writeln('diem m o phia ngoai da giac ');
readln;
END.
4 Đa giác lồi
Bài tốn 5: Kiểm tra một đa giác có là đa giác lồi hay khơng. Để kiểm
tra tính lồi của đa giác, với mọi cạnh nối đỉnh i với đỉnh (i+1) (i từ 1 đến n,
đỉnh n+1 coi như đỉnh 1) mọi đỉnh j (j từ 1 đến n) và đỉnh (i+2) phải ln ln
cùng phía so với đường thẳng chứa cạnh i(i+1)
Uses crt;
const max = 20;
fi= 'dg_loi.inp';
12
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
type toado = array[1..max] of real;
var x,y : toado;
n: word;
procedure input;
var i : word;
f : text;
begin
assign(f,fi); reset(f);
readln(f,n);
for i:=1 to n do
readln(f,x[i],y[i]);
close(f);
end;
function cungfia(x1,x2,x3,x4,y1,y2,y3,y4: real):boolean;
var d1,d2: real;
begin
d1: = (y3y1)*(x2x1)(x3x1)*(y2y1);
d2: = (y4y1)*(x2x1)(x4x1)*(y2y1);
cungfia:=d1*d2>=0;
end;
function dg_loi: boolean;
var i,j,k,l : word;
begin
for i:=1 to n do
begin
k: = i+2;
13
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
l: = i+1;
if k=n+1 then k: = 1;
if l=n+1 then l: = 1;
for j:=1 to n do
if (j<>i) and ( not
cungfia(x[i],x[l],x[j],x[k],y[i],y[l],y[j],y[k]))
then
begin
dg_loi: = false;
exit;
end;
end;
dg_loi: = true;
end;
BEGIN
clrscr;
input;
if dg_loi then writeln('da giac loi ')
else writeln('da giac khong loi ');
END.
5 Tìm đường bao lồi chứa tập điểm cho trước
Bài 6: Cho N điểm a1,a2,..., an trên mặt phẳng. Các điểm có toạ độ
ngun và khơng có 3 điểm nào thẳng hàng. Hãy viết chương trình xác định một
đa giác khơng tự cắt có các đỉnh là một số điểm trong n điểm đã cho và chứa tất
cả các điểm cịn lại, đồng thời có chu vi nhỏ nhất. Hãy tính diện tích đa giác này
Dữ liệu vào cho trong file DAGIAC.INP gồm n+1 dịng
14
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
Dịng 1 chứa số N.
N dịng tiếp theo: dịng i trong n dịng này chứa toạ độ (xi,yi) của điểm ai
Dữ liệu ra ghi vào file DAGIAC.OUT:
Dịng 1 ghi 3 số k, v, s với k là số đỉnh đa giác tìm được, v là chu vi và s là
diện tích của nó.
Dịng i+1 (1 i k ) ghi toạ độ của đỉnh thứ i của đa giác.
Ghi chú: các số thực có phần thập phân có 2 số lẻ
Ví dụ
DAGIAC.INP
5
0 1
4 4
0 4
4 0
2 2
DAGIAC.OUT
4 15.12 14.00
4 4
0 4
0 1
3
0
15
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
* Phương pháp 1: Dựa vào định nghĩa đa giác lồi
Trước hết cần chú ý đa giác khơng tự cắt có các đỉnh là một số điểm trong
n điểm đã cho và chứa tất cả các điểm cịn lại, đồng thời có chu vi nhỏ nhất đó
chính là đường bao lồi chứa các điểm đã cho mà các đỉnh của bao lồi thuộc tập
đỉnh đã cho.
Để tìm bao lồi này theo định nghĩa đa giác lồi, ta thực hiện như sau:
+ Tìm 2 điểm: x0, x1 chắc chắn thuộc bao lồi: đó là 2 điểm nằm trên một
đường thẳng d sao cho mọi điểm cịn lại đều ở cùng một phía của d.
+ Tìm điểm tiếp theo là xi (chọn trong các điểm cịn lại chưa trong bao lồi)
sao cho với mọi điểm j ln cùng phía với x0 so với đường thẳng qua xi, x1.
+ Lại coi j là xi và tiếp tục tìm j mới cho đến khi khơng cịn tìm được nữa
Uses crt;
const max = 100;
fi = 'baoloi.inp';
fo = 'baoloi.out';
type toado = array[1..max] of real;
var x,y,ly : toado;
b : array[1..1000] of boolean;
ds: array[1..1000] of integer;
n,top : integer;
f : text;
procedure input;
var i: integer;
f : text;
begin
assign(f,fi);
15
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
reset(f);
readln(f,n);
for i:=1 to n do
readln(f,x[i],y[i]);
close(f);
end;
function cungfia(x1,x2,x3,x4,y1,y2,y3,y4: real): boolean;
var d1,d2: real;
begin
d1: = (y3y1)*(x2x1)(x3x1)*(y2y1);
d2: = (y4y1)*(x2x1)(x4x1)*(y2y1);
cungfia:=d1*d2>=0;
end;
function timhaidiem(var i,j: integer): boolean;
var k,l: integer;
begin
for k:=1 to n do
for l:=1 to n do
if (ki)*(kj)*(li)*(lj)<>0 then
if not cungfia(x[i],x[j],x[k],x[l],y[i],y[j],y[k],y[l]) then
begin
timhaidiem: = false;
exit;
end;
timhaidiem: = true;
end;
16
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
function dientich: real;
var s,min: real;
i,j: integer;
begin
ly: = y;
min: = 10000; { tinh tien da giac doc truc oy sao cho
da giac nam hoan toan phia tren truc ox}
for i:=1 to top do
if y[ds[i]]
if min<0 then
for i:=1 to top do y[ds[i]]: = y[ds[i]] min;
s: = 0;
for i:=1 to top do
begin
j: = i+1;
if i=top then j: = 1;
s: = s+((x[ds[j]]x[ds[i]])*(y[ds[j]]+y[ds[i]]))/2;
end;
dientich: = abs(s);
end;
function timk: integer; { tim diem tiep theo cua duong bao quanh }
var i,j,l,k: integer;
ok: boolean;
begin
timk:=0;
i: = ds[top1];
17
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
j: = ds[top];
for k:=1 to n do
if not b[k] then
begin
ok: = false;
for l:=1 to n do
if (l<>k) then
if not cungfia(x[j],x[k],x[i],x[l],y[j],y[k],y[i],y[l]) then
begin
ok: = true;
break;
end;
if not ok then
begin
timk: = k;
exit;
end;
end;
end;
procedure work2; { tim duong da giac loi chua tap diem da cho }
var i,j,k,l,t: integer;
min: real;
ok: boolean;
begin
fillchar(b,sizeof(b),false);
for i:=1 to n do
begin
18
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
ok: = true;
for j:=1 to n do
if (j<>i) and timhaidiem(i,j) then
begin
ds[1]: = i;
ds[2]: = j;
top: = 2;
b[i]: = true;
b[j]: = true;
ok: = false;
break;
end;
if not ok then break;
end;
repeat
k: = timk;
if k<>0 then
begin
inc(top);
ds[top]
:= k;
b[k]
:= true;
end;
until k=0;
end;
function chuvi: real;
var i,j: integer;
c: real;
19
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
begin
c: = 0;
for i:=1 to top do
begin
j: = i+1;
if i=top then j: = 1;
c: = c + sqrt(sqr(x[ds[j]]x[ds[i]])+
sqr(y[ds[j]]y[ds[i]]));
end;
chuvi: = c;
end;
BEGIN
clrscr;input;
work2;
assign(f,fo); rewrite(f);
writeln(f,top,' ',chuvi:8:2,' ',dientich:8:2);
for n:=1 to top do writeln(f,x[ds[n]]:4:0,' ',ly[ds[n]]:4:0);
close(f);
END.
* Phương pháp 2: (wrap: bọc gói)
Trước hết chọn một điểm chắc chắn thuộc bao lồi (thí dụ điểm có tung
độ nhỏ nhất), gọi điểm này là điểm A. Kẻ tia Ax cùng chiều dương của trục
hồnh. Quay tia Ax xung quanh A một góc V cho đến khi chạm điểm đầu tiên
của tập điểm đã cho, đó là điểm thuộc bao lồi. Lại gọi điểm này là A, lại tạo tia
Ax, quay góc V1 cho đến khi chạm điểm đầu tiên của tập điểm thì điểm mới này
lại là một điểm của bao lồi. Q trình cứ tiếp diễn như vậy cho đến khi điểm
mới tìm được trùng với điểm A ban đầu.
20
Một số phương pháp hình học cơ bản để giải quyết các bài tốn Tin học
Chú ý rằng ln ln có V1 > = V. Mặt khác, thực chất chúng ta cũng
khơng quay tia Ax mà “quay một cách hình thức” như sau: Ta tính tất cả các góc
Vb tạo bởi tia Ax và tia AB (B là mọi điểm chưa thuộc bao lồi), V b nào nhỏ nhất
sẽ được chọn làm V và điểm B tương ứng sẽ là điểm được đưa vào bao lồi.
Điều chú ý thứ hai là: Đặt dy=(yb ya); dx=(xb xa ), ay=|dy|, ax=|dx|
Để tính các góc V, đáng lẽ tính ta tính V= arctang(dy/dx ), nhưng ta thay bằng
tính t=dy/(ax+ay) vì có thể chứng minh khi t và V dương thì t đồng biến theo V
(V tăng thì t cũng tăng). Nhờ đó có thể xử lý tốt trong những trường hợp sau:
+ Nếu dx = 0 thì cho góc=90 độ
+ Nếu dy = 0 và dx >0 thì góc = 0 độ
+ Nếu dy = 0 và dx <0 thì cho t=90 độ và góc = 2*t = 180 độ
+ Nếu góc là tù thì góc = (2 t) * 90 độ
+ Nếu góc > 180 độ thì góc = (4+t) * 90 độ ( t<0 vì trong trường hợp này dy<0)
Ngồi ra khi đọc chương trình dưới đây cũng cần lưu ý kỹ thuật dùng biến
rất tiết kiệm bằng cách: mỗi khi được một đỉnh thuộc bao lồi thì chứa ngay vào
phần đầu của mảng P chứa tập điểm đã cho. Cụ thể nếu đã được m đỉnh của
bao lồi thì m phần tử đầu của mảng P là những đỉnh này, để tìm đỉnh thứ m+1
của bao lồi chỉ cần duyệt trên mảng P từ m+1 đến n+1 (n+1 là đỉnh 1 ). Giả sử
tìm được đỉnh thứ m+1 của bao lồi là phần tử thứ i thì đổi chỗ phần tử thứ i này
cho phần tử thứ m+1 của P.
Uses crt;
const max = 20;
fi = 'baoloi.inp';
fo = 'baoloi.out';
type diem = record x,y: real end;
dagiac = array[1..max] of diem;
var p: dagiac;
21