1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài toán ông sao Start

16 537 1
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 16
Dung lượng 72,5 KB

Nội dung

Bài toán ông sao Start

Trang 1

Một ông sao sáng, hai ông sáng sao

Nguyễn Xuân Huy Bạn đếm có thạo không?

Chúng ta học đếm từ tấm bé nhưng hình như chưa thật thạo Nhiều khi chúng ta lúng túng không biết vận dụng các kỹ thuật đếm vào việc giải các bài toán tin học Bài này giới thiệu với bạn đọc một vài kỹ thuật đếm khá phổ biến trong tin học

Đếm theo phần

Người xưa đếm sao trên trời theo kiểu "Một ông sao sáng, hai ông sángsao " Đã bao giờ bạn thử tìm hiểu ý nghĩa của câu hát trên chưa? Xinmách bạn rằng, cho đến tận ngày nay, các nhà thiên văn vẫn áp dụng, phương pháp đơn giản này để đếm sao đấy Bản chất của

kỹ thuật này là như sau Ngườita chia các ngôi sao trên bầu trời theo từng nhóm căn cứ vào cấp độ sáng củachúng Các sao sáng nhất gọi là sao cấp 0, sau đó đến các sao cấp 1, cấp 2, Rồi người ta đếm theo từng nhóm Dĩ nhiên là bầu trời mênh mông, số lượng saolà vô hạn, đếm mãi cũng không xuể Ta đang nói đến việc đếm các ngôi sao nhìnthấy được bằng mắt thường Ta thử vận dụng kỹ thuật đếm theo nhóm để giải bàitoán-tin học sau đây

Bài 1 (Sơn cột, bài thi học sinh giỏiquốc gia, khối B) Trên mảnh đất hình chữ nhật kích

thước m x n ô vuông đơn vị,người ta xây các cột bê tông hình vuông tại các ô Mỗi cột bao gồm một số khốilập phương đơn vị chồng lên nhau Các cột có thể cao thấp khác nhau Sau đóngười ta sơn các mặt bê tông nhìn thấy được của các cột Tính diện tích cầnsơn

Dữ liệu vào: Ghi trong tệp văn bản COT.INP, dòng đầu tiên là hai giá trị m và n.Tiếp theo đó là m dòng, mỗi dòng có n số tự nhiên biểu thị chiều cao đo bằng sốlượng khối lập phương tạo nên cột bê tông tại vị trí đó

m, n và chiều cao của mỗi cột không quá 100

Dữ liệu ra: Hiển thị trên màn hình diện tích cần sơn tính theo ô vuông đơn vị

Thí dụ, với m=3, n=4 và tệp COT.INP có dạng sau:

COT.INP

3 4

1 0 3 1

Trang 2

2 2 0 1

0 0 1 4

Thì sau khi thực hiện chương trình trên màn hình phải xuất hiện giá trị

5 4

Lời giải

Gọi mảnh đất hình chữ nhật là ABCD Ta đếm từng mặt theo trật tự tuỳ ý, chẳng hạn:

1 Đếm số khối trên hai chiều dài AB và DC

2 Đếm số khối trên hai chiều rộng AD và BC

3 Đếm số khối nhìn thấy theo chiều ngang giữa các hàng

4 Đếm số khối nhìn thấy theo chiều dọc giữa các cột

5 Đếm số khối trên mặt

Trong chương trình SONCOT.PAS dưới đây thủ tục DOS sẽ đọc dữ liệu từ tệp COT.INT vào mảng a Thủ tục Xem hiển thị giá trị của mảng a trên màn hình Thủ tục Dem thực hiện giải thuật 5 bước nói trên

Chương trình Pascal

(*SONCOT.PAS*)

uses crt;

const fn = 'COT.INP'; MN=100;

var f:text;

a: array[1 MN, 1 MN] of byte;

{chua du lieu doc tu tep}

d: longint; {dien tich can so}

m,n: integer; {chieu dai va rong cua manh dat}

{Doc du lieu tu tep vao mang a}

Trang 3

procedure DocTep;

var i, j: byte;

begin

assign(f,fn);

reset(f);

read(f,m,n);

for i:=1 to m do

for j:=1 to n do read(f,a[i,j]);

close(f);

end;

{Hien thi du lieu tren man hinh de kiem tra} procedure Xem;

var i,j:integer;

begin

writeln('m= ',m, 'n= ',n);

for i:=1 to m do begin writeln;

for j:=1 to n do write(a[i,j]:4);

end;writeln;

end;

{Dem dien tich can so}

procedure Dem;

var i,j: byte;

begin

Trang 4

{Dem theo 2 chieu dai AB và CD}

for j:=1 to n do d:=d+a[1,j]+a[m,j]

{Dem theo 2 chieu rong AD va BC}

fori:=1 to m do d:=d+a[i,1]+a[i,n]

{Dem so khoi nhin thay theo chieu ngang giua cac hang} fori:=2 to m do

for j:=1 to n do

d:=d+abs(a[i,j]-a[i-1,j]);

{Dem so khoi nhin thay theo chieu doc giua cac cot} forj:=2 to n do

for i:=1 to m do

d:=d+abs(a[i,j]-a[i,j-1]);

{Dem mat tren}

fori:=1 to m do

for j:=1 to n do

if a[i,j]>0 then d:=d+1;

end;

BEGIN

DocTep;

Xem;

Dem;

writeln(d);

Trang 5

Du lieu test:

COT.INP

3 4

1 0 3 1

2 2 0 1

0 0 1 4

Ket qua du kien: 5 4

Dưới đây là chương trình viết bằng ngôn ngữ C trong môi trường Turbor C hoặc C++

Chương trình C

/*SONCOT.C*/

#include

#include

#include

#define fn "COT.INP"

#define MN 100

#define byte unsigned char

void DocTep();

void Xem();

void Dem();

FILE *f;

byte a[MN][MN];

long d; /*Dien tich can so*/

Trang 6

int m,n;

main()

{clrscr();

DocTep();

Xem();

Dem();

printf("%d",d);

getch();

}

/*Doc du lieu tu tep vao mang a */

void DocTep()

{byte i,j;

f=fopen(fn,"rt");

fscanf(f, "%d", &m, &n);

for (i=0; i<>

for (j=0; j<>

fscanf(f, "%d", &a[i][j]);

fclose(f);

}

/* Hien thi du lieu tren man hinh de kiem tra */ void Xem()

{byte i,j;

prinf("m=%d n=%d n",m,n);

Trang 7

for (i=0;i<M;++I)< p> {printf("n");

for (j=0;j<N;++J)< p> printf("%4d", a[i][j]); }

printf("n");

}

/*Dem dien tich can son */ voidDem()

{byte i,j;

d=0;

for(j=0;j<N;++J)< p> d+=a[0][j]+a[m-1][j]; for(i=0;i<M;++I)< p> d+=a[i][0]+a[i][n-1]; for(i=1;i<M;++I)< p> for(j=0;j<N;++J)< p> d+= abs(a[i][j]-a[i-1][j]); for(j=1;j<N;++J)< p>

? for(i=0;i<M;++I)< p> d+=abs(a[i][j]-a[i][j-1]); for(i=0;i<M;++I)< p> for(j=0;j<N;++J)< p>

Trang 8

d++;

}

Ketqua du kien: 5 4

Duyệtmột lần, ghi theo loại

Đểkiểm phiếu người ta thường đọc một lần các lá phiếu Với mỗi lá phiếu người tachọn

và ghi thêm một đơn vị cho mỗi đại biểu được bầu Chúng ta sẽ vận dụng kỹthuật này để giải bài toán thoạt xem tưởng như khó sau đây

Bài2 Tệp văn bản DAYSO.INP chứa nhiềudẫy số Mỗi dẫy số gồm N giá trị nguyên

a1,a2, ,aN, 2< N< 2000 Hãy viếthàm DangDieu kiểm tra dáng điệu của các giá trị trong mỗi dãy Hàm cho ra cácgiá trị nhận biết sau đây:

1: Nếu dãy đã cho là đồng nhất, a1=a2= =aN

2: Nếu dãy đã cho là tăng chặt, a1 > a2 > > aN

3: Nếu dãy đã cho là đồng biến, a1 ≥ a2 ≥ ≥ aN

4: Nếu dãy đã cho là giảm chặt, a1 < a2 < < aN

5: Nếu dãy đã cho là nghịch biến, a1 ≤ a2 ≤ ≤ aN

0: Nếu không xảy ra các trường hợp 1 5

Lời giải

Ta lần lượt đọc và so sánh hai phần tử đứng liên tiếp nhau vào hai biến tương ứng là asau

và atruoc

- Nếu asau=atruoc ta tăng con đếm b

- Nếu asau > atruoc ta tăng con đếm t

-Nếu asau < atruoc ta tặng con đếm g

Nói một cách hình ảnh, ta sử dụng ba cái lọ b và t và g Lọ b dùng để đếm các cặp phần

tử bằng nhau, lọ t đếm các cặp phần tử tăng và lọ g đếm các cặp phần tử giảm Ta mang theo ba lọ b,t và g và một nắm hạt ngô rồi đi dạo trên dãy số, xuất phát từ phần tử đầu tiên là a1 Mỗi lần bước sang phần tử tiếp theo ta so sánh phần tử đó với phần tử trước Nếu hai phần tử bằng nhau thì bỏ một hạt ngô vào lọ b Nếu phần tử sau lớn hơn phần tử

Trang 9

trước thì bỏ một hạt ngô vào lọ t Nếu phần tử sau nhỏ hơn phần tử trước ta bỏ một hạt ngô vào lọ g Tổng cộng ta bước N-1 bước, mỗi bước sử dụng đúng một hạt ngô để bỏ vào một trong ba lọ Vậy ta có: b+t+g=N-1 Hệ thức này gợi ý cho ta chỉ sử dụng hai thay

vì ba lọ Tachọn b và t

Saukhi đến đích ta tính giá trị g theo công thức g=N-1-t-b rồi chỉ cần lắc các lọlà có thể biết được dáng điệu của dãy đã cho

Nếulọ kêu, tức là trong lọ có ngô ta ghi 1, ngược lại, nếu lọ rỗng ta ghi 0 Giátrị nh phân thu được của ba lọ xếp theo thứ tự gtb sẽ cho dáng điệu của dãy số.Để ý hai trường hợp cuối cùng 110 và 111 ứng với các giá trị 6 và 7 Các trườnghợp này cho biết dãy vừa có khúc tăng vừa có khúc giảm (Xem bảng dưới)

Bảng1 Lắc các lọ g, t và b ta có thể xácđịnh dáng điệu của dãy a.

Lọkêu: 1, lọ không kêu: 0; Cột dáng điệu cho ra giá trị thập phân, trong ngoặc làgiá trị nhị phân tương ứng

Chươngtrình dưới đây đọc dữ liệu từ tệp văn bản DAYSO.INP nhiều dãy số vào mảng a rồixác định dáng điệu của dãy số đó và hiển thị kết quả trên màn hình Để kiểm

thửchương trình bạn cần tạo trước tệp văn bản DAYSO.INP và nạp các dãy số Với mỗidãy cần có một số N cho biết số lượng các phần tử trong dãy đó tiếp đến là N sốtrong dãy Tệp kiểm thử DAYSO.INP dưới đây chứa 6 dãy với các dáng điệu khácnhau

{DANGDIEU.PAS}

Trang 10

(*Chuy: Ban can tao truoc tep du lieu Test DAYSO.INP *) usescrt;

constfn='DAYSO.INP'; MN=2000;

varf:text;

a: array [0 MN] of integer;

{Du lieu trong day}

n: integer;

{So luong phan tu trong moi day}

{Hien thi du moi day}

procedureXemDuLieu;

vari:integer;

begin

writeln; write(' N= ',n); writeln;

for i:=1 to n do write(a[i]:4); writeln;

end;

functionDangDieu: integer;

varg, t, b, i: integer;

{ba lo g, t, b va con duyet i}

begin

t:=0, b:=0;

for i:=2 to n do

if(a[i]=a[i-1]) then inc(b)

else if(a[i]>a[i-1]) then inc(t);

Trang 11

if g>0 then g:=1;

if t >0 then t:=1;

if b>0 then b:=1;

i:=4*g+2*t+b;

if i>5 then DangDieu:=0

else DangDieu:=i;

end;

procedureRun;

vari: integer;

begin

assign(f,fn);

reset(f);

whilenot eof(f) do begin

read(f,n);

ifn=0 then begin close(f); exit; end; fori:=1 to n do read(f,a[i]);

XemDuLieu;

write('DangDieu=',DangDieu,':'); case DangDieu of

0: writeln('Tang giam');

1: writeln('Dong nhat');

2: writeln('Tang chat');

Trang 12

3: writeln('Dong bien');

4: writeln('Giam chat');

5: writeln('Nghich bien');

end;end;

end;

BEGIN

Run;

readln;

END

Dulieu Test gom 6 day so co dang dieu khac nhau: DAYSO.INP

5

3 3 3 3 3

7

1 40 50 60 77 100 102

8

1 3 3 9 9 9 40 105

7

100 80 77 14 10 5 1

7

100 80 80 14 10 5 1

7

19 9 3 2 2 1

Trang 13

/*DANGDIEU.C */

/*Chuy: Ban can tao truoc tep du lieu test SAP.INP */

#include

#include

#include

#include

#definefn "DAYSO.INP"

#defineMN 2000

#definebyte unsigned char

/*Thiet ke */

voidXemDuLieu();

intDangDieu();

voidRun();

FILE*f;

inta[MN]; /* Chua du lieu cua moi day */

intn; /* So phan tu trong moi day */

main()

{Run();

getch();

}

/*Hien thi mot day */

voidXemDuLieu()

{int i;

Trang 14

printf("n N=%d n",n);

for(i=0;i<N;++I)< p>

printf("%4d", a[i]);

printf("n");

}

intDangDieu()

{int g, t, b, i; /* Ba lo g, t, b va con duyet i */ t=b=0;

for(i=1;i<N;++I)< p>

if(a[i]==a[i-1]) ++b;

??else if(a[i]>a[i-1]) ++t;

g=n-1-t-b;

if (g>0)

g=1;

if (t>0)

t=1;

if (b>0)

b=1;

i=4*g+2*t+b;

return (i>5)? 0:i;

}

voidRun()

{ int i;

Trang 15

f=fopen(fn,"r");

while (!feof(f))

{ fscanf(f,"%d",&n);

if(n==0)

{ fclose(f);

return;

}

for(i=0;i<N;++I)< p>

fscanf(f,"%d",&a[i]);

fscanf(f,"n");

XemDuLieu();

i=DangDieu();

printf("DangDieu=%d: ",i);

switch(i)

{ case 0: printf("Tang giam"); break; case 1: printf("Dong nhat"); break; case 2: printf("Tang chat"); break; case 3: printf("Dong bien"); break; case 4: printf("Giam chat"); break; case 5: printf("Nghich bien"); break; }

}

Trang 16

}

Ngày đăng: 07/09/2012, 10:53

HÌNH ẢNH LIÊN QUAN

Bảng1. Lắc các lọ g ,t và b ta có thể xácđịnh dáng điệu của dãy a. - Bài toán ông sao Start
Bảng 1. Lắc các lọ g ,t và b ta có thể xácđịnh dáng điệu của dãy a (Trang 9)

TỪ KHÓA LIÊN QUAN

w