Thứ Hai, 26 tháng 11, 2012

Dùng vòng lặp xử lí bài toán

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 = \sum\limits_{i = 0}^{n - 1} {{{({a_i} - Max)}^2}} + \sum\limits_{i = 0}^{n - 1} {{{(a{}_i - Min)}^2} + \frac{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.
Giải:
Đặt vấn đề:
Thoạt đầu khi nhìn vào bài toán chúng ta sẽ nghĩ đến việc dùng một vòng lặp để nhập dãy n số thực rồi sau đó đi tìm giá trị Min, Max để tính Aver cũng bằng vòng lặp
Vấn đề: Nếu thực hiện như thứ tự trên thì ta buộc phải dùng nhiều hơn một vòng lặp cho nên không thỏa yêu cầu của đề bài đưa ra.
Đề bài cũng không cho phép ta dùng mảng để đưa trước các số thực vào mảng.
Vì vậy ta phải tìm cách để gộp các bước lại với nhau để hạn chế lại số vòng lặp cần dùng.

Cách giải quyết bài toán:
Ta đã biết trước được dãy gồm có n số thực ${a_0},{a_1},{a_2},...,{a_{n - 1}}$ nhập vào theo thứ tự và ta cũng dễ dàng so sánh các phần tử với nhau. Do đó ta nghĩ đến việc vừa nhập dãy số vào vừa tìm Min, Max của dãy số bằng cách:


  • Nhập vào phần tử đầu tiên ${a_0}$.
  • Gán $Min = Max = {a_0}$.
  • Tiếp tục nhập vào các phần tử tiếp theo và so sánh với $Min$, $Max$.

Xét biểu thức Aver, ta có:
$\sum\limits_{i = 0}^{n - 1} {{{({a_i} - Max)}^2}} = \sum\limits_{i = 0}^{n - 1} {a_i^2} - 2Max\sum\limits_{i = 0}^{n - 1} {{a_i}} + n.Ma{x^2}$
$\sum\limits_{i = 0}^{n - 1} {{{({a_i} - Min)}^2}} = \sum\limits_{i = 0}^{n - 1} {a_i^2} - 2Min\sum\limits_{i = 0}^{n - 1} {{a_i}} + n.Mi{n^2}$
$ \Rightarrow Aver = 2\sum\limits_{i = 0}^{n - 1} {a_i^2} - 2(Max + Min).\sum\limits_{i = 0}^{n - 1} {{a_i}} + n(Ma{x^2} + Mi{n^2}) + \frac{n}{2}{(Max - Min)^2}$ (1)
Từ (1) ta lại lồng ghép tính $\sum\limits_{i = 0}^{n - 1} {a_i^2} $ và $\sum\limits_{i = 0}^{n - 1} {{a_i}} $ vào vòng lặp trên.
Sau cùng tính giá trị của $Aver$ và in kết quả, kết thúc bài toán.


Thuật toán:
Nhập vào số phần tử n của dãy.
Cho i chạy từ 1 đến n để nhập phần tử và tìm  $Min$, $Max$ đồng thời tính tổng  ${S_1} = \sum\limits_{i = 0}^{n - 1} {a_i^2} $ và ${S_2} = \sum\limits_{i = 0}^{n - 1} {{a_i}} $.
Dùng giá trị   $Min$, $Max$ tìm được tính $Aver$.
Xuất kết quả ra màn hình.

Source code:

#include <stdio.h>
#include <conio.h>
void main()
{
       double a, aver, min, max, s1, s2;
       int n;
       printf("Nhap vao so phan tu n cua day: ");
       scanf("%d", &n);
       printf("Nhap vao phan tu a0 cua day: ");
       scanf("%lf", &a);
       min = max = a;
       s1 = a*a;
       s2 = a;
       for (int i = 1; i < n; i++)
       {
             printf("Nhap vao phan tu a%d cua day: ", i);
             scanf("%lf", &a);
             s1 = s1 + a*a;
             s2 = s2 + a;
             if (a < min)
                    min = a;
             if (a > max)
                    max = a;
       }
       aver = 2*s1 - 2*(max + min)*s2 + n*(max*max + min*min) + 0.5*n*(max - min)*(max - min);
       printf("Gia tri cua Aver la: %lf\n", aver);
       getch();
}

Không có nhận xét nào:

Đăng nhận xét