7) Khái quát hóa
CHƯƠNG II: GỢI ĐỘNG CƠ TRUNG GIAN 1) Hướng đích
1) Hướng đích
Xuất phát từ bài toán giải phương trình bậc hai:
Var a, b, c, d: Real;
Begin
Writeln('Nhap 3 he so cua phuong trinh:'); Write('a = '); Readln(a);
Write('b = '); Readln(b); Write('c = '); Readln(c); If a = 0 Then
If b = 0 Then
Else Writeln('Phuong trinh vo nghiem!')
Else Writeln('Phuong trinh co mot nghiem: x = ',-c/b:0:1) Else Begin
d := b * b - 4 * a * c;
If d < 0 Then Writeln('Phuong trinh vo nghiem!') Else
If d = 0 Then Writeln('Phuong trinh co nghiem kep: x1 = x2 = ',-b / (2 * a):0:1)
Else Begin
Writeln('Phuong trinh co hai nghiem phan biet:'); Writeln('x1 = ',(-b + sqrt(d)) / (2 * a):0:1); Writeln('x2 = ',(-b - sqrt(d)) / (2 * a):0:1); End; End; Readln End.
Mục tiêu là chia bài toán ban đầu thành những bài toán nhỏ độc lập. Chẳng hạn:Ta sử dụng chương trình con thành hai bài toán :
T1: Giải phương trình bậc nhất T2: Giải phương trình bậc hai
Var a, b, c: Real;
Procedure ptb1(m,n:Real); Begin
If m = 0 Then
If n = 0 Then Writeln('Phuong trinh co vo so nghiem!') Else Writeln('Phuong trinh vo nghiem!')
End;
Procedure ptb2(x, y, z: Real); Var d: Real;
Begin
D := y * y - 4 * x * z;
If d < 0 Then Writeln('Phuong trinh vo nghiem!') Else
If d = 0 Then Writeln('Phuong trinh co nghiem kep: x1 = x2 = ',-y / (2 * x):0:1)
Else Begin
Writeln('Phuong trinh co hai nghiem phan biet:'); Writeln('x1 = ',(-y + sqrt(d)) / (2 * x):0:1);
Writeln('x2 = ',(-y - sqrt(d)) / (2 * x):0:1); End;
End;
Begin
Writeln('Nhap 3 he so cua phuong trinh:'); Write('a = '); Readln(a); Write('b = '); Readln(b); Write('c = '); Readln(c); If a=0 Then ptb1(b, c) Else ptb2(a, b, c); Readln End.
Ta lại thấy trong bài toán trên việc giải phương trình bậc hai có ba trường hợp xảy ra. Ta nên chia tiếp thành 5 bài toán nhỏ như sau:
T1: Giải phương trình bậc nhất T2: ∆ > 0
T3: ∆ = 0 T4: ∆ < 0
T5: Giải phương trình bậc hai
Var a, b, c, d: Real;
Procedure ptb1(m, n : Real); Begin
If m = 0 Then
If n = 0 Then Writeln('Phuong trinh co vo so nghiem!') Else Writeln('Phuong trinh vo nghiem!')
Else Writeln('Phuong trinh co mot nghiem: x = ',-n / m:0:1) End;
Procedure denta_am; Begin
Writeln('Phuong trinh vo nghiem!'); End;
Procedure denta_0(p, q: Real); Begin
Writeln('Phuong trinh co nghiem kep: x1 = x2 = ',-q / (2 * p):0:1) End;
Procedure denta_duong(i, j: Real); Begin
Writeln('Phuong trinh co hai nghiem phan biet:'); Writeln('x1 = ',(-j + sqrt(d)) / (2 * i):0:1);
Writeln('x2 = ',(-j - sqrt(d)) / (2 * i):0:1); End;
Procedure ptb2(x, y, z: Real); Begin
d := y * y - 4 * x * z; If d < 0 Then denta_am Else
If d = 0 Then denta_0(x, y) Else denta_duong(x, y); End;
Begin
Writeln('Nhap 3 he so cua phuong trinh:'); Write('a = '); Readln(a); Write('b = '); Readln(b); Write('c = '); Readln(c); If a = 0 Then ptb1(b, c) Else ptb2(a, b, c); Readln End. 2) Quy lạ về quen Xét bài toán : Tính k n
C . Học sinh đã biết công thức : Ck k!(nn! k)!
n = − . Bài toán
này ta quy về bài toán quen thuộc là tính n! Ở đây chúng ta cần lưu ý với học sinh rằng: Để tính k
n
C ta cần xây dựng chương trình con tính n! sau đó, ta tìm k n
C bằng công thức trên. Tuy nhiên, cũng cần phải xây dựng một chương trình con Nhap
để tránh việc người sử dụng nhập các số âm và nhập k > n.
Var k, n: Integer; C:Real;
Procedure Nhap; Begin
Repeat
Write('Nhap n = '); Readln(n);
If (k < 0) Or (n < 0) Or (k > n) Then Writeln('Nhap lai!'); Until (k > 0) And (n > 0) And (k < n);
End;
Function GT(a:Integer): Integer; Var kq, i:Integer; Begin kq:=1; For i:=1 to a do kq:=kq * i; GT:=kq; End; Begin Nhap; C := GT(n) / (GT(k) * GT(n - k)); Writeln('C = ', C:0:0); Readln End. 3) Xét tương tự
Xuất phát từ bài toán: “Tính n! bằng thuật toán đệ quy”.
Var n: Integer;
Function GT(a:Integer): Real; Begin If a = 0 Then GT:=1 Else GT:=GT(a - 1) * a; End; Begin Write('Nhap n = '); Readln(n);
Writeln(n,'! = ', GT(n):0:0); Readln
End.
Tương tự, chúng ta yêu cầu học sinh thực hiện giải bài toán: “Tính an bằng thuật toán đệ quy”
Var a, n: Integer;
Function Mu(x:Integer; y:Integer):Real; Var T: Real; Begin If y = 0 Then Mu:=1 Else Begin Mu:=Mu(x, y - 1) * x; End; End; Begin Write('Nhap a = '); Readln(a); Write('Nhap n = '); Readln(n); Writeln(a,' mu ',n,' = ',Mu(a , n):0:0); Readln End.
4) Khái quát hóa
Xuất phát từ bài toán: “Sắp xếp ba số a, b, c theo thứ tự tăng dần”.
Var a,b,c: Real;
Procedure Sapxep(Var x, y, z: Real); Var tg: Real;
Begin If x > y Then Begin tg := x; x := y; y := tg; End; If y > z Then Begin tg := y; y := z; z := tg; End; If x > y Then Begin tg := x; x := y; y := tg; End; End; Begin
Writeln('Nhap vao ba so: '); Write('So thu nhat: '); Readln(a); Write('So thu hai : '); Readln(b); Write('So thu ba : '); Readln(c); Sapxep(a, b, c);
Writeln('Ba so sau khi sap xep la:'); Write(a:6:0, b:6:0, c:6:0);
Readln
End.
Ở đây chúng ta cần lưu ý với học sinh rằng : lệnh gán nhận giá trị mới thì mất giá trị cũ. Vì vậy mà trước khi thực hiện lệnh gán x := y để máy nhận giá trị của b ta phải gửi giá trị cũ của x vào biến tg. Tại sao lệnh thứ ba lại giống lệnh thứ nhất? đó là vì x, y, z, tg là các địa chỉ lưu trữ những giá trị. Những giá trị này bị thay đổi qua những lệnh gán. Địa chỉ của biến thì không đổi, nhưng nội dung của biến thì đã thay đổi khi thực hiện lệnh gán.
Tiếp theo, chúng ta có thể nêu câu hỏi: Khái quát,nếu phải sắp xếp n số theo thứ tự tăng dần ta phải làm thế nào? Ta có chương trình như sau:
Var a: Array[1..100] Of Real; i,j,n: Integer;
Procedure Doicho(Var x,y:Real); Var tg:Real; Begin Tg := x; x := y; y := tg; End; Procedure Sapxep; Begin For i := 1 to n - 1 do For j := i + 1 to n do
If a[i] > a[j] Then Doicho(a[i], a[j]); End;
Begin
Write('Nhap so phan tu cua day so: '); Readln(n); For i := 1 to n do Begin
Write('So thu ',i,': '); Readln(a[i]); End;
Sapxep;
Writeln('Day so sau khi sap xep la:'); For i := 1 to n do Write(a[i]:6:0); Readln
End.