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.