November 25, 2012

ĐỒ ÁN MÔN HỌC NM CNTT1 - BÀI 2

ĐỒ ÁN MÔN HỌC NM CNTT1
LỚP CỬ NHÂN TÀI NĂNG KHÓA 2012
Giảng viên ra đề:
ThS. Trương Phước Hưng


Bài 2: Xem công thức tính sau đây (đề thi tuyển sinh cao học ngành KHMT, năm 2011):
  Aver = Σ(ai – Max)2 + Σ(ai – Min)2 + n/2(Max – Min)2

Trong đó Max, Min lần lượt là giá trị lớn nhất, nhỏ nhất của n số thực (được nhập vào từ thiết bị nhập chuẩn) a0, a1, …, an-1.
Chỉ dùng duy nhất 1 vòng lặp (for hoặc while), đề xuất cách thức để nhập n số thực như trên và tính giá trị của biểu thức Aver, xuất kết quả tính ra thiết bị xuất chuẩn. Viết chương trình để minh họa đề xuất đó.
Lưu ý: Phần này sinh viên chưa học về mảng, như vậy vấn đề chính của bài toán này là không thể dùng mảng để lưu giá trị của n số thực nói trên. Như vậy phải đề xuất một giải pháp “thông minh” để nhập và tính toán mà không đưa trước các số thực này vào mảng.

Bài làm
-         Nhận xét ban đầu:
o   Rõ ràng điểm khó nhất bài này là tìm cách giải mà chỉ dùng 1 vòng lặp. Bởi vì với công thức đã cho, ta hoàn toàn có thể giải bằng 2 vòng lặp bằng cách cho vòng lặp thứ nhất nhập số vào và đồng thời tìm Max, Min của dãy số, còn vòng lặp thứ 2 thì tính toán theo công thức.
o   Do đề bài có nói rõ là không dùng mảng, vậy ta sẽ phải dùng 1 vòng lặp vừa nhập, vừa tính toán rồi sau đó in ra kết quả.

-         Theo công thức đề bài, ta phải biết sẵn Max và Min của dãy số ở mỗi lần lặp. Vậy không thể tính thẳng theo công thức này được mà phải biến đổi nó. Cách biến đổi đơn giản nhất chính là bung hằng đẳng thức ra:
o   Aver = Σ(ai – Max)2 + Σ(ai – Min)2 + n/2(Max – Min)2
= Σ(ai2 – 2aiMax + Max2) + Σ(ai2 – 2aiMin + Min2) + n/2(Max – Min)2
= Σai2 – 2MaxΣai + ΣMax2 + Σai2 – 2MinΣai + ΣMin2 + n/2(Max – Min)2
= 2Σai2 – 2(Max + Min)Σai + n(Max2 + Min2) + n/2(Max – Min)2

o   Đến đây, ta thấy rằng mỗi số hạng đều có thể tính độc lập với nhau:
§  2Σai2: dùng vòng for tính tổng ai2 rồi nhân kết quả cho 2.
§  – 2(Max + Min)Σai: dùng vòng for tính tổng ai và lưu Max, Min của dãy số rồi nhân với -2(Max + Min).
§  n(Max2 + Min2): dùng 1 vòng for lưu Max, Min của dãy số, tính Max + Min rồi nhân với n.
§  n/2(Max – Min)2: dùng 1 vòng for lưu Max, Min của dãy số, tính (Max – Min)2 rồi nhân với n/2.

-         Nếu làm như trên ta sẽ cần ít nhất 4 vòng lặp, thế nhưng nếu nhìn kĩ ta sẽ thấy trong một vòng lặp hoàn toàn có thể dùng nhiều biến để lưu trữ và tính toán tất cả các giá trị cần thiết cho cả 4 số hạng trên. Sau đó, khi thoát khỏi vòng lặp, ta sẽ dùng những giá trị đã tìm được để tính ra kết quả như công thức.

Mã nguồn
#include <iostream>
#include <iomanip>
using namespace std;
void main()
{
 int iN;
 double dA, dMin, dMax, dTong = 0, dTongMu2 = 0, dSoHang1, dSoHang2, dSoHang3, dSoHang4, dKetQua;

 cout << "Nhap so phan tu N: ";
 cin >> iN;
 for (int i = 0; i < iN; i++)
 {
  cout << "Nhap phan tu thu " << i + 1 << " :";
  cin >> dA;
  if (i == 0)
  {
   dMin = dA;
   dMax = dA;
  }
  if (dMin > dA) 
   dMin = dA;
  if (dMax < dA)
   dMax = dA;
  dTong += dA;
  dTongMu2 += dA * dA;
 }

 dSoHang1 = 2 * dTongMu2;
 dSoHang2 = -2 * dTong * (dMax + dMin);
 dSoHang3 = iN * (dMax * dMax + dMin * dMin);
 dSoHang4 = 0.5 * iN * (dMax - dMin) * (dMax - dMin);
 dKetQua = dSoHang1 + dSoHang2 + dSoHang3 + dSoHang4;

 cout << "Ket qua bai toan la: " << fixed << setprecision(9) << dKetQua << endl;
}


No comments:

Post a Comment