1. Trang chủ
  2. » Vật lí lớp 11

Dap an HSG Tin lop 11 nam 20132014

9 12 0

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 9
Dung lượng 266,77 KB

Nội dung

toán nào mà ch ỉ sử dụng trong phạm vi Pascal để giải quyết mọi trường hợp bài toán đặt. ra hay không[r]

(1)

SỞ GD& ĐT NGHỆ AN ĐỀ THI CHỌN HỌC SINH GIỎI TỈNH LỚP 11 NĂM HỌC 2013-2014

(Đề gồm trang)

Môn thi: TIN HỌC – THPT BẢNG A

Thời gian: 150 phút(không kể thời gian giao đề)

Bài Tên file nguồn File Input File Outout Thời gian chạy Điểm

Bài THANHGO.PAS THANHGO.INP THANHGO.OUT giây

Bài MIN.PAS MIN.INP MIN,OUT giây

Bài SDD.PAS SDD.INP SDD.OUT giây

Baì SUBARR.PAS SUBARR.INP SUBARR.OUT giây

Bài (5 điểm)

THANH GỖ

Cha Pinocchio muốn làm lại cho Picochio mũi Ơng có N gỗ,

thanh gỗ i có độ dài Là người yêu thích tốn học ơng ta đưa giải thuật sau để

lấy gỗ có độ dài cần thiết:

- Nếu lại gỗ ơng ta lấy gỗnày làm mũi cho Pinocchio - Nếu cịn nhiều gỗ ông ta làm sau:

Bước 1: Chọn gỗ i có độ dài nhỏ nhất, chọn gỗ j có độ

dài ajnhỏ lại

Bước 2: Nếu ai= ajthì vứt bỏ bớt thanh, quay Bước

Bước 3: Nếu ai< ajthì cắt khỏi ajđi đoạn ai, quay lại Bước u cầu:Hãytính độ dài gỗ mà ơng ta nhận để làm mũi cho Pinocchio

Giới hạn:1<=N <=10.000; 1<=ai<=109

Dữ liệu: Vào từ file văn THANHGO.INP: Dòng số N, dòng sau N số a1, a2, …., an

Kết quả: Ghi file văn THANHGO.OUT:Số X độ dài gỗ tìm

(Các số dịng file liệu vào cách ký tự trống) Ví dụ

THANHGO.INP THANHGO.OUT

3

1

Bài (6 điểm)

SỐ NHỎ NHẤT

Cho số nguyên dương K xâu ký tự S Xâu S gồm ký tự chữ

cái la tinh thường ‘a’… ‘z’ chữ số ‘0’… ‘9’, có K ký tự chữ số

Bạn viết chương gtrình loại bỏ số ký tự khỏi xâu S cho K ký tự

lại theo thứ tự tạo nên số nhỏ Trong K ký tự cịn lại cho phép

chữ số đứng đầu

Dữ liệu vào: Vào từ file văn MIN.INP: Dòng thứ số nguyên dương K

(K<=10) Dòng thứ hai ghi xâu S có độ dài nhỏ 250

Kết quả: Ghi file văn MIN.OUT: Gồm dòng ghi K ký tự lại tạo

nên số nhỏ

(2)

Ví dụ:

MIN.INP MIN.OUT

4

307uv5xly08mnp 0108

Bài (5 điểm)

SỐ ĐƠN ĐIỆU

Số a1, a2, … , an gọi số đơn điệu < ai+1 > ai+2 hoặcai > ai+1 < ai+2 (Với

mọi i = n-2) Số có chữ số; số có hai chữ số khác gọi số đơn điệu có độ dài 1;

Ví dụ: số 5, 58, 3748, 32435465768 số đơn điệu vì: Số có chữ số

Số 58 có chữ số khác

Số 3748 có 3<7>4<8

Số 32435465768 ta thấy: 3>2<4>3<5>4<6>5<7>6<8

Yêu cầu:Viết chương trình xác định số chữ số lớn tạo thành số đơn điệu

một số cho trước

Dữ liệu: Vào từ file văn SDD.INP: Gồm số nguyên dương N có khơng q

75 số

Kết quả: Ghi file văn SDD.OUT: Chứa số nguyên số chữ số lơn tạo

thành số đơn điệu số N Ví dụ:

SDD.INP SDD.OUT

3748

Bài (4 điểm)

SUBARRAY

Cho dãy số nguyên a1, a2, … aN số nguyên dương K Dãy ai, ai+1, … aj

(1<=i<=j<=N) dãy đượctạo từ phần tử liên tiếp dãy A, phần tử i kết thúc phần từ j

Yêu cầu:Tìm số lượng dãy A có K phần tử Dữ liệu:Vào từ file văn SUBARR.INP:

Dòng cứa số nguyên dương N, K (1<=k<=N<=4.105) Dòng thứ chứa N

số nguyên a1, a2, … aN(ai<=109)

Kết quả:Ghi file văn SUBARR.OUT: Ghi số lượng dãy tìm

(Các số dịng file liệu vào ghi ký tự

trống) Ví dụ:

SUBARR.INP SUBARR.OUT

4 2

3

-

(3)

HƯỚNG DẪN GIẢI

(Hướng dẫn mức độ người giải, nên hồn tồn khơng phải đáp án Vì có thể có nhiều lỗi khơng thể lấy 100% điểm tối đa đề ) Bài 1.

- Về liệu:

+ Có N gỗ N<=10.000 Cần màng 10.000 phầntử

+ Các Ai<=109 phải sử dụng kiểu Longint, longint chiếm byte

Nên tổng nhớ chiếm toàn là: 10.000 x = 40.000byte đáp ứng đủ - Về thuật tốn:

+ Nếu cịn lấy làm Mũi

+ Nếu ta thực bước

Bước 1: Chọn Ai nhỏ thanh, chọn Aj nhỏ thứ 2(chọn

nhỏ nhất)

Bước 2: Nếu Ai = Ajthì bỏ quay Bước (Bỏ Ai) Bước 3: Nếu Ai<Ajthì lấy Aj= Aj- Airồi quay Bước

Ta nhận thấy: Nếu bước chọn phần tử nhỏ nhất, sau Bước phần tử

là nhỏ nhất.Vì ta nhận thấy Bước tạo nên thuật tốn Tìm UCLN số nhỏ

nhất dãy Khi tìm ước chung số nhỏ lấy ước số nhỏ

tiếp theo để tìm UCLNBài tốn trở thành tốn: TÌM ƯỚC CHUNG LỚN

NHẤT CỦA dãy số

Như mặt kết ta tìm CULN được, chẳng cần phải từ từ tìm số nhỏ

nhất Nhưng liệu nhỏ nên code có phần xếp ý đồ yêu cầu bước thuật toán

Program THANHGO;

const fi='THANHGO.INP o='THANHGO.OUT Var a:array[1 10000] of longint; i,j,l,n:longint;

Procedure DocDL;

Begin

assign(input,fi); reset(input); readln(n);

for i:=1 to n read(A[i]); close(input);

End;

Procedure SapXep;

var tg,csm:longint; Begin

for i:=1 to n -1 Begin

csm:=i;

for j:= i+1 to n

(4)

Begin tg:=A[i]; A[i]:=A[csm]; A[csm]:=tg End;

End; End;

Function Cat(a,b:integer):integer;

{thực tế hàm UCLNnhưng thay sử dụng phép Trừ sử dụng phép Chi cho nhanh}

Begin

while (a<>0) and (b<>0) if a>b then a:=a mod b else b:=b mod a; if a<>0 then Cat:=a else Cat:=b; End;

Procedure Xuly;

Begin

for i:=1 to n-1

A[i+1]:=Cat(A[i],A[i+1]); End;

Procedure LuuKQ;

Begin

assign(output,fo); rewrite(output); write(A[n]);

close(output); End;

Begin

DocDL; XuLy; LuuKq;

End. Bài 2:

- Về mặt liệu:Bài yêu cầu liệu xâu có độ dài khơng q 250 phần tử Nó xâu bình thường Pascal

+ K <=10 nên số nhỏ có tối đa 10 chữ số (longint đủ)

+Số nhỏ chứa số đầuSố nhỏ số cần xử lý phần chữ

số đứng đầu Đơn giản ta để XÂU(khi để xâu K khơng cịn quan trọng nữa)

- Về thuật tốn (u cầu): Tìm số nhỏ lấy từ xâu S

+ Rõ ràng ta cần tách ramột xâu gồm ký tự chữ Số riêng (không tách điều kiện

(5)

+ Ta cần tìm K phần tử xâu chử số: Mỗi phần tử số nhỏ có

dãy xét:

Chú ý: Khi ta chọn phần tử thứ ithì ta phải dành cho K – i phần tử cuối cho phần tử Tức K = 10 ta chọn chữ số cho vị trí thứ ta phải

dành 10-1=9 chữ số cuối cho chữ số lại

function Min(i,j:byte):byte;

var csm:byte; Begin

csm:=i;

for i:=i+1 to j if S[csm]>S[i] then csm:=i;

Min:=csm;

Hàm trả vị tríký tự nhỏ xâu S kể từ vị trí I đến vị trí J Khi tìm chữ số i=1

Khi tìm vị trí chữ số xnào đóthì i bắt đầu tính từ i trước cộng với Thuật tốn đầy đủ là:

Program MIN;

const fi='MIN.INP'; fo='MIN.OUT'; Var S,s1:string;

i,l,j,k:byte;

Procedure DocDL;

Begin

assign(input,fi); reset(input); readln(k);

readln(s); close(input); End;

Function Loc(S:string):string;

var i:byte; tam:string; Begin

tam:='';

for i:=1 to length(s)

if('0'<=S[i]) and (S[i]<='9') then tam:=tam+S[i];

Loc:=tam; End;

function Min(i,j:byte):byte;

var csm:byte; Begin

csm:=i;

(6)

if S[csm]>S[i] then csm:=i;

Min:=csm; End;

Procedure Xuly;

Begin

s:=Loc(s); l:=length(s); s1:='';

i:=0;

for j:=1 to k Begin

i:=Min(i+1,l-k+j); s1:= s1+ S[i] End;

End;

Procedure LuuKQ;

Begin

assign(output,fo); rewrite(output); write(s1);

close(output); End;

Begin

DocDL; XuLy; LuuKq;

End. Bài 3:

- Về mặt liệu: Số xét có tối đa 75 chữ số, điều kiện đơn điệu xét cho chữ số dãy số Dãy chữ số Số LỚN Vì ta nên sử dụng Xâu để lưu số lớn - Về mặt thuật toán: Bài giống dạng tìm đoạn đơn điệu tăng/giảm dài dãy số Thông thường gặp dạng ta sữ dụng số để lưuvị trí Đầu

tiên Kết thúc dãy dãy đơn điệu độ dài dãy đơn điệu dài Kết thúc dãy bắt đầu dãy

Thuật toán

Program SODD;

const fi='SDD.INP'; fo='SDD.OUT'; Var A:string;

d:byte;

Procedure DocDL;

Begin

(7)

close(input); End;

Procedure Xuly;

var l,i,j:byte; d1:byte; Begin

l:=length(a);

a:=a+a[l]; {mục đích để thuật toán dùng A[L]}

j:=1;

for i:=2 to l

if not (((a[i-1]<a[i] ) and( a[i]>a[i+1] ))or ((a[i-1]>a[i] ) and( a[i]<a[i+1] ))) then Begin

d1:=i-j+1;

if d1>d then d:=d1; j:=i;

End;

if d=0 then d:=l; {Nếu có phần tử For chạy,nếu có phần tử For khơng chạy D=0 nen d lấy L=1}

End;

Procedure LuuKQ;

Begin

assign(output,fo); rewrite(output); write(d);

close(output); End;

Begin

DocDL; XuLy; LuuKq;

End.

Bài (4 điểm)

SUBARRAY

Cho dãy số nguyên a1, a2, … aN số nguyên dương K Dãy ai, ai+1, … aj

(1<=i<=j<=N) dãy tạo từ phần tử liên tiếp dãy A, phần tử i kết thúc phần từ j

Yêu cầu:Tìm số lượng dãy A có K phần tử Dữ liệu:Vào từ file văn bảnSUBARR.INP:

Dòng cứa số nguyên dương N, K (1<=k<=N<=4.105) Dòng thứ chứa N

số nguyên a1, a2, … aN(ai<=109)

Kết quả:Ghi file văn SUBARR.OUT: Ghi số lượng dãy tìm

(Các số dịng file liệu vào ghi ký tự

(8)

- Về mặt liệu: Ai<=1.000.000.000 nên phải dùng Longint Byte

+ Gồm 400.000 phần tửBộ nhớ cần cấp 400.000 x = 1.600.000Bvượt mức cho

phép Pascal Đây vấn đề lớn, lẽ chương trình THPT hướng dẫn

khuôn khổ Pascal mà Nhưng thực tế phần mềm chấm điểm lại sử dụng

dịch Free Pascalvì bạncó thểkhai báo lớn nhiều sơ với Pascal

Đây điều thắc mắc đề thi năm gần Liệu có thuật

tốn mà sử dụng phạm vi Pascal để giải trường hợp tốn đặt

ra hay khơng?

Nếu bạn lo nhớ lớn khuyên tạora nhiều code vớicác liệu lớnvà nhỏ tách riêng Nhằm lấy tối đa Test

Một vấn đề là: dãy có 400.000 phầntử cả, với k=2 số lượng

dãy số có phần tử 400.000 + 399.999 + 399.998 + +1+0 ~= 40

tỷthì số Ngun khơng thể chứa ngoại trừ Int46 Free Pascal, Cịn khơng

ta sử dụng số thực với kiểu Double

Là câu khó vì:Ta phải kiểmtra tất cácdãy có độ dài lớn kvới số lượng phần tử 400.000 phần tử Thuật tốn khơng khó, chắn vấp

phải thời gian chạy (chạy thời gian xét dãy 1) - Thuật toán:

+ Ta sử dụng mảng để lưu Số lượng phần tử có dãy

+ Dãy xét i, bổ sung phần tử j vào, bổ sung phần tử tăng

biến đếm phần tử lên Nếu biến đếm = K ta thấy đoạn Ai Ajlà dãy

thảo mãnđoạn Ai Ajlà đoạn Ai ANnên ta có N-j+1 dãy

+ Ta tăng i lên để xét doạn tiếp theo, tăng i tức ta loại bỏ Aira khỏi danh sách cần từ biếm đếm phần tử Ai.Sau tăng i ta tiếp tục kiểm tra số lượng phần

tử dãy chỉ cần kiểm tra phần tử Aj(Loại bỏ giảm số lượng phần tử,

giảm phần tử vừa bổ sung Ajmới giảm)

Trong biến I chạy từ đến N-K +1; J chạy từ đến N biến chạy nhau, tuỳ trường hợp mà tăng không tăng nên ta phải dùng lặp While

Program SUBARRAY;

const fi='SUBARR.INP'; fo='SUBARR.OUT'; Var

A:Array[1 400000] of longint;

D:Array[1 1000000000] of word; {K~65000} sl:int64;

i,j,n,k:longint;

Procedure DocDL;

Begin

assign(input,fi); reset(input); readln(n,k);

(9)

Procedure XuLy;

Begin i:=1; j:=0;

while (i<=n-k+1)and(j<=n) Begin

if D[A[j]]<k then Begin

j:=j+1;

D[A[j]]:=D[A[j]]+1; End

Else

Begin

sl:=sl+1+N-j;

D[A[i]]:=D[A[i]]-1; i:=i+1;

End; End;

End;

Procedure LuuKq;

Begin

assign(output,fo); rewrite(output); write(sl);

close(output); End;

Begin

DocDL; XuLy; LuuKq;

Ngày đăng: 04/03/2021, 10:25

TỪ KHÓA LIÊN QUAN

w