Đề thi, hướng dẫn làm các bài trong đề thi và bộ test dùng để chấm điểm. Chỉ cần tải về làm rồi dùng chương trình Themis để chấm bài. Nếu không làm được thì đọc hướng dẫn làm bài và đọc chương trình tôi đã viết. Cảm ơn
Trang 1SỞ GIÁO DỤC VÀ ĐÀO TẠO
THANH HOÁ
ĐỀ CHÍNH THỨC
KỲ THI HỌC SINH GIỎI TỈNH
Năm học: 2015-2016 Môn thi: Tin học Lớp 12 THPT
Ngày thi: 10/03/2016
Thời gian: 180 phút (không kể thời gian giao đề)
Đề này có 03 câu, gồm 02 trang.
T ng quan b i thi:ổng quan bài thi: ài thi:
Câu Tên bài Tên file nguồn Tên file input Tên file output Điểm
* Dữ liệu vào là đúng đắn, không cần phải kiểm tra Các số trên một dòng ghi cách nhau ít nhất một dấu cách.
Hãy lập trình giải các bài toán sau:
Bài 1: Cực tiểu:
Cho một dãy số gồm N số nguyên a1, a2, , aN Người ta định nghĩa một số ai là cực tiểu địa phương nếu thỏa mãn ai-1 > ai < ai+1 (a1 và aN không được gọi là cực tiểu địa phương) Hãy tìm số lượng cực tiểu địa phương của dãy số trên
Input: Cho trong file văn bản BAI1.INP gồm:
- Dòng 1 chứa duy nhất một số nguyên dương N (N ≤ 106)
- Dòng 2 chứa dãy số nguyên a1, a2, , aN (|ai| ≤ 109, )
Output: Kết quả ghi ra file văn bản BAI1.OUT duy nhất một số là kết quả của bài
toán
Ví dụ:
4
2 3 2 3
1
Bài 2: Mật khẩu:
Một xâu ký tự được gọi là mật khẩu "an toàn" nếu thỏa mãn các điều kiện: Độ dài của xâu đó >= 6, chứa ít nhất một chữ cái in hoa ('A' 'Z'), chứa ít nhất một chữ cái thường ('a' 'z') và chứa ít nhất một chữ số ('0' '9')
Số báo danh
……….
Trang 2Ví dụ: 'a1B2C3', 'tinHoc6' là hai mật khẩu "an toàn", còn 'a1B2C', 'a1b2c3', 'A1B2C3', 'tinhoc' đều không phải là mật khẩu "an toàn"
Cho một xâu S mà mỗi ký tự trong S thuộc một trong ba loại sau: Chữ cái in hoa ('A' 'Z'), chữ cái thường ('a' 'z'), chữ số ('0' '9') Tìm xem có bao nhiêu cặp chỉ số (i,j) thỏa mãn điều kiện: 1 <= i < j <= length(s) và xâu con gồm các ký tự liên tiếp từ i đến j của S là mật khẩu "an toàn"
Input: Cho trong file văn bản BAI2.INP gồm duy nhất một dòng chứa xâu S có độ dài
không quá 5000 kí tự
Output: Kết quả ghi ra file văn bản BAI2.OUT một số nguyên là số lượng cặp chỉ số
(i,j) tính được
Ví dụ:
Bài 3: Dãy con :
Cho một dãy số nguyên dương gồm N phần tử a1, a2, , aN và một số nguyên dương k
Một dãy thu được từ dãy ban đầu bằng cách loại bỏ đi một số phần tử và giữ nguyên thứ tự các phần tử còn lại (có thể không loại bỏ phần tử nào) được gọi là dãy con của dãy ban đầu Hãy tìm các dãy con của dãy đã cho có tổng các phần tử bằng k
Input: Cho trong file văn bản BAI3.INP gồm 2 dòng:
- Dòng đầu ghi hai số nguyên N và k ( 0< N 500; 0< k 50000)
- Dòng tiếp theo ghi N số nguyên a1, a2, , aN (0 < ai 106, với )
Output: Kết quả ghi ra file văn bản BAI3.OUT, có cấu trúc như sau:
- Nếu không có dãy con nào thỏa mãn đề bài thì ghi số: 0
Trang 35 16
1 5 8 10 20
1 5 8 10 20 2
2
(Có 30% số test trong tổng các test của bài 3 là chỉ có 1 dãy con thỏa mãn và các phần tử được chọn là liên tiếp)
Hết
Trang 4-Bài 1: Dùng vong FOR duyệt 1 lần là OK
const fi='bai1.inp';
fo='bai1.out';
var f:text;
n,i,j,d:longint;
a:array[1 1000000] of longint;
begin
assign(f,fi);
reset(f);
readln(f,n);
for i:=1 to n do
read(f,a[i]);
close(f);
d:=0;
for i:=2 to n-1 do
if (a[i-1]>a[i]) and (a[i]<a[i+1]) then
inc(d);
assign(f,fo);
rewrite(f);
write(f,d);
close(f);
end.
Trang 5Bài 2: Có nhiều cách để làm bài này Nhưng cách tối ưu nhất vẫn là qui hoạch động trên 3 mảng
Gọi a[i] là số kí tự loại chữ số từ S1 đến Si
Gọi b[i] là số kí tự loại chữ cái in hoa từ S1 đến Si
Gọi c[i] là số kí tự loại chữ cái thường từ S1 đến Si
const fi='bai2.inp';
fo='bai2.out';
var f:text;
s:ansistring;
n,i,j,d:longint;
a,b,c:array[0 5000] of longint;
begin
assign(f,fi);
reset(f);
readln(f,s);
close(f);
n:=length(s);
for i:=1 to n do
begin
if (s[i]>='0') and (s[i]<='9') then
a[i]:=a[i-1]+1
else
a[i]:=a[i-1];
if (s[i]>='A') and (s[i]<='Z') then
b[i]:=b[i-1]+1
else
b[i]:=b[i-1];
if (s[i]>='a') and (s[i]<='z') then
c[i]:=c[i-1]+1
else
c[i]:=c[i-1];
end;
d:=0;
for i:=1 to n-5 do
for j:=i+5 to n do
if (a[j]>a[i-1]) and (b[j]>b[i-1]) and (c[j]>c[i-1]) then
d:=d+1;
assign(f,fo);
rewrite(f);
write(f,d);
close(f);
end.
Trang 6Bài 3: Đây là bài qui hoạch động
Dùng mảng b với ý nghĩa
b[i]=true nếu ta có thể chọn trong dãy một số phần tử có tổng bằng i
b[i]=false nếu ta không thể chọn trong dãy một số phần tử có tổng bằng i
Xét từng phần tử a[i]
Nếu b[j-a[i]]=true thì b[j]=true (vì khi đó thêm a[i] vào dãy có tổng bằng j-a[i] ta sẽ được dãy có tổng bằng j)
Để truy vết ra dãy ta dùng mảng pre
Để đếm số lượng dãy ta dùng mảng sl
const fi='bai3.inp';
fo='Bai3.out';
var f:text;
d,i,j,n,k:longint;
a,c:array[1 500] of longint;
pre,sl:array[0 50000] of longint;
b:array[0 50000] of boolean;
begin
assign(f,fi);
reset(f);
readln(f,n,k);
for i:=1 to n do
read(f,a[i]);
close(f);
b[0]:=true;
sl[0]:=1;
d:=0;
for i:=1 to n do
for j:=k downto a[i] do
if b[j-a[i]] then
begin
b[j]:=true;
sl[j]:=sl[j]+sl[j-a[i]];
if pre[j]=0 then
pre[j]:=a[i];
end;
assign(f,fo);
rewrite(f);
if sl[k]<>1 then
write(f,sl[k])
else
Trang 7End.
Trang 10Một số test chấm