Tải bản đầy đủ (.doc) (11 trang)

De va dap an MON TIN ky thi HSG tinh THANH HOA nam hoc 2016 2017

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.92 MB, 11 trang )




Bài 1: Viết hàm kiểm tra tính nguyên tố hoặc dùng sàng nguyên tố để làm
const fi='Bai1.inp';
fo='Bai1.out';
var f:text;
d,n,x:longint;
{============================}
function NTO(n:longint):boolean;
var i:longint;
begin
if n<2 then
exit(false);
for i:=2 to trunc(sqrt(n)) do
if n mod i=0 then
exit(false);
exit(true);
end;
{============================}
BEGIN
assign(f,fi);
reset(f);
readln(f,n);
close(f);
d:=0;
for x:=2 to n div 2 do
if NTO(x) and NTO(n-x) then
inc(d);
assign(f,fo);
rewrite(f);


write(f,d);
close(f);
END.


Bài 2: Dùng đếm phân phối
const fi='Bai2.inp';
fo='Bai2.out';
var f:text;
s:string;
dem,i:longint;
d:array['0'..'z']of byte;
c:char;
begin
assign(f,fi);
reset(f);
readln(f,s);
close(f);
for i:=1 to length(s) do
inc(d[s[i]]) ;
assign(f,fo);
rewrite(f);
dem:=0;
for c:='0' to 'z' do
if d[c]>0 then inc(dem);
writeln(f,dem);
for c:='A' to 'Z' do
if d[c]>0 then
writeln(f,c,' ',d[c]);
for c:='a' to 'z' do

if d[c]>0 then
writeln(f,c,' ',d[c]);
for c:='0' to '9' do
if d[c]>0 then
writeln(f,c,' ',d[c]);
close(f);
end.


Bài 3: Dùng phương pháp duyệt 2 điểm hoặc tìm kiếm nhị phân để làm
Cách 1: Tìm nhị phân
const fi='Bai3.inp';
fo='Bai3.out';
var f:text;
i,r:longint;
res,d,c,g,vt,n:int64;
a:array[1..300000]of longint;
begin
assign(f,fi);
reset(f);
readln(f,n,r);
for i:=1 to n do
read(f,a[i]);
close(f);
res:=0;
for i:=1 to n-1 do
begin
d:=i+1;
c:=n;
vt:=n+1;

while d<=c do
begin
g:=(d+c) div 2;
if a[g]>a[i]+r then
begin
vt:=g;
c:=g-1;
end
else
d:=g+1;
end;
res:=res+n-vt+1;
end;
assign(f,fo);
rewrite(f);
writeln(f,res);
close(f);
end.


Cách 2: Dùng phương pháp duyệt 2 điểm
const fi='Bai3.inp';
fo='Bai3.out';
var f:text;
d:array[1..300000] of longint;
j,n,r,i:longint;
dem:int64;
begin
assign(f,fi);
reset(f);

readln(f,n,r);
for i:=1 to n do
read(f,d[i]);
close(f);
dem:=0;
i:=1;
j:=2;
while (i<=n-1) and (j<=n) do
if d[j]-d[i]>r then
begin
dem:=dem+n-j+1;
inc(i);
end
else
inc(j);
assign(f,fo);
rewrite(f);
write(f,dem);
close(f);
end.


Dùng 2 biến i và j. Biến i chạy theo biểu thức 2k+1 biến j chạy theo biểu thức 3k+1
const fi='Bai4.INP';
fo='Bai4.OUT';
var f:text;
a:array[1..1000000] of longint;
i,j,k,n:longint;
begin
assign(f,fi);

reset(f);
readln(f,n);
close(f);
a[1]:=1;
i:=1;
j:=1;
for k:=2 to n do
if 2*a[i]<3*a[j] then
begin
a[k]:=2*a[i]+1;
inc(i);
end
else
if 2*a[i]=3*a[j] then
begin
a[k]:=2*a[i]+1;
inc(i);
inc(j);
end
else
begin
a[k]:=3*a[j]+1;
inc(j);
end;
assign(f,fo);
rewrite(f);
write(f,a[n]);
close(f);
end.



Dùng phương pháp duyệt 2 điểm
Nếu đoạn Si …Sj có đúng k bít 1 thì khi đó số đoạn con liên tiếp chúa k bít 1 từ Si … Sj
là (a[i-1]+1)(b[j+1]+1) trong đó a[i-1] là số bít 0 liên tiếp đứng trước Si, b[j+1] là số bít 0 liên
tiếp đứng sau Sj
Chú ý xử lý trường hợp k=0
const fi='Bai5.inp';
fo='Bai5.out';
var f:text;
s:ansistring;
res:qword;
n,k,l,i,j,d:longint;
b,c:array[0..1000001]of longint;
begin
assign(f,fi);
reset(f);
readln(f,k);
readln(f,s);
close(f);
n:=length(s);
assign(f,fo);
rewrite(f);
b[0]:=0;
for i:=1 to n do
if s[i]='1' then
b[i]:=0
else
b[i]:=b[i-1]+1;
if k=0 then
begin

res:=0;
for i:=1 to n do
res:=res+b[i];
write(f,res);


end
else
begin
if n-b[n]res:=0
else
begin
c[n+1]:=0;
for i:=n downto 1 do
if s[i]='1' then
c[i]:=0
else
c[i]:=c[i+1]+1;
i:=1;
while s[i]='0' do
inc(i);
d:=0;
for j:=i to n do
if s[j]='1' then
begin
d:=d+1;
if d=k then
break;
end;

res:=(b[i-1]+1)*(c[j+1]+1);
d:=0;
for l:=j+1 to n do
if s[l]='1' then
inc(d);
for l:=1 to d do
begin
i:=i+1;
while s[i]='0' do
inc(i);
j:=j+1;


while s[j]='0' do
inc(j);
res:=res+(b[i-1]+1)*(c[j+1]+1);
end;
end;
writeln(f,res);
end;
close(f);
end.



×