PDA

View Full Version : 4 bài pascal tỉnh



okmen910
05-03-2008, 17:01
Mời mọi người giải thử
-Bài 1:Viết chương trình tạo một mảng A[1..n,1..n], với n được nhập từ bàn phím(n<=20), các phần tử của mảng là các số tự nhiên được sinh ngẫu nhiên có giá trị từ 0->99. Hãy săp xếp mảng A theo yêu cầu: Với k là số tự nhiên được nhập từ bàn phím, néu k là số chẵn thì sắp xếp các phần tử của mảng theo thứ tự tăng dần theo hình xoắn ốc cùng chiều kim đồng hồ, ngược lại thì sắp xếp các phần tử của mảng có thw tự tăng dần theo hình xoắn ốc ngược chiều kim đồng hồ

-Bài 2:Tính tổng số ngày giữa hai mốc thời gian bấy kì được nhập từ bàn phím. Biết rằng: Số nàgy trong các tháng 1,3,5,7,8,10,12 là 31 ngày; Số ngày trong các tháng 4,6,9,11 là 30 ngày; Riêng tháng 2 có 29 ngày nếu năm dố là năm nhuận, năm không nhuận thì có 28 ngày. Năm nhuận là năm chia hét cho 400 hoặc chia hết cho 4 mà không chia hết cho 100
+Giả thiết: nàgy đã được nhập hợp lệ
+Ví dụ:
1. từ ngày 23/03/2007 đến nàgy 24/03/2007 thì số ngày là 2 ngày
2, Từ nàgy 23/03.2007 đến ngày 03/04/2007 thì số ngày là 12 ngày

<<Còn hai bài nữa sẽ post lên sau>>

m2mpro
05-03-2008, 17:56
Bài 1 : Dùng if và mảng hằng để quay
Bài 2 : Lại dùng if :D

phuclun
05-03-2008, 20:19
theo hình xoắn ốc là sao???

mr_invincible
05-03-2008, 22:34
Theo hình xoắn ốc là ... điền các số theo hình xoắn ốc chứ là gì :D
Dạo này thấy lắm đề thi học sinh giỏi quá nhỉ

mr_invincible
05-03-2008, 22:36
Bài 1 : Dùng if và mảng hằng để quay


Quay gì đâu bạn, chỉ cần chia trường hợp ra mà làm thôi, hai cái gần như giống hệt nhau, copy rồi sửa một chút là xong

okmen910
06-03-2008, 15:15
theo hình xoắn ốc là sao???

ví dụ
1 2 3
8 9 4
7 6 5
<<Mời mọi người giải tiếp>>

Bài 3:Xét tập F(N) tất cả các số hữu tỷ trong đoạn [0,1] với mẫu số không quá N
Ví dụ F(5):0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1
Hãy viết chương trình cho phép nhập số nguyên N nằm trong khoảng 1 đến 100 và xuất ra theo thứ tự tăng dần các phân số trong tập F(N) cùng số lương các phân số đó
Ví dụ nhập N=5
0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1
Tất cả có 11 phân số

Bài 4:Có 5 người đàn ông và 1 con khỉ trên đảo hoang và hằng ngày hị thu gom những quả dừa để đến một ngày nào đó họ sẽ cùng phân chia. Thế rồi trong một đêm, một người đần ông trong số họ thức dậy để cầm chắc phần của mình: Ông ta chia các quả dừa thành 5 đống bằng nhau thì thấy dư một quả . Con khỉ nhận được quả đó. Người đàn ông giấu phần của mình đi và xếp những quả dừa lại với nhau. Trong mỗi đêm , việc này còn diễn ra trong 4 lần nữa và mỗi làn con khỉ nhạn được 1 quả dừa. Rồi một buổi sáng những người đàn ông cùng phân chia đống dừa còn lại thành 5 phần bằng nhau thì thấy không dư quả nào. Hỏi ban đầu có bao nhiêu quả dừa? Giả thiết từ lúc đàn ông xấu tính thực hiện ý đồ của mình thì không có quả dừa nào được nhặt thêm. Viết chương trình dể giải bài toán trên

okmen910
06-03-2008, 15:30
em đã làm bài 4 mà sao nó ra kết quả là 2496 quả, mọi người xem giúp em

uses crt;
var kt:boolean;
sodu,lay,soqua,n,i,j:integer;
begin
clrscr;
kt:=false;
n:=6;
while not(kt) do
begin
kt:=true;
soqua:=n;
for i:=1 to 4 do
begin
sodu:=soqua mod 5;
lay:=soqua div 5;
soqua:=soqua-lay-sodu;
if sodu<>1 then kt:=false;
end;
if (soqua mod 5<>0) or (soqua=0) then kt:=false;
if kt then writeln('So qua ban dau la ',n,' qua');
inc(n,5);
end;
readln;
end.

mr_invincible
06-03-2008, 22:13
Bài 3 đã có trong diễn đàn rồi, hình như sử dụng công thức. Mà hình như trong tạp chí Tin học và nhà trường số gần đây cũng mới có về vấn đề này. Bạn chịu khó tìm lại nhé :D

anhem115
10-03-2008, 15:01
Okmen910 này, bạn ở khánh hòa phải không, mình ở ninh hòa nè. Bạn có thể post đề thi chọn học sinh giỏi tin tỉnh vòng 2 năm 2006-2007 và 2005-2006 ( cả 2 vòng) cho mình được không, mình bị thất lạc mất rồi. Cảm ơn bạn trước

okmen910
12-03-2008, 16:00
bốn bài này đấy bạn anhem

anhem115
13-03-2008, 18:36
Thế đề năm 2006 -2007 vòng 2 gồm những bài nào, năm 2004 2005 là bài nào bạn có thể kể cụ thể không? gần thi đến nơi rồi, cảm ơn nhiều!

m2mpro
14-03-2008, 11:35
Bạn thấy bài nào thì cứ làmbài đó đi. chọn lọc làm chi :D

anhem115
14-03-2008, 11:43
cái bài phân số trong [0,1] mình làm thế này có được không
tử :=1 to n
mẫu:=1 to n
if nguyêntốcùngnhau(tử,mẫu)=true và tử <mẫu thì
begin a[i]:=tử/mẫu(chuyển sang số thực);b[i]:='tử/mẫu';
sau đó mình sắp xếp b[i] dựa theo a[i]--> kết quả

Hú hú, có ai có giải thuật chia kẹo mà không dính tới đệ qui không zậy, chỉ với!

okmen910
15-03-2008, 16:16
bạn anhem115 gì đó ơi, bài 3 đâu có nói về số nguyên tố đâu bạn, nó muốn nói số hữu tỷ mà, cái ví dụ mình cho:
F(5)=0/1(=0) 1/5(=0.2) 1/4(=0.25) 1/3(=0.333) 2/5(=0.4) 1/2(=0.5) 3/5(=0.6) 2/3(=0.666) 3/4(=0.75) 4/5(=0.8) 1/1(=1)
=>để ý thấy thì mấy số trong ngoặc khác nhau tăng dần và thuộc trong [0..1]

tuansando
15-03-2008, 21:44
Bài chia kẹo thì theo mình dùng theo đệ quy dễ làm hơn, mấy anh lớn bảo vậy

boysitinh_vl
15-03-2008, 22:22
lo mấy topic kia bỏ quên topic này nay vô giải cho
bài xoắn ốc:

procedure dien(var x1,y1,x2,y2:byte;var x:integer);
var i,j:integer;
begin
if (x1=x2) and (y1=y2) then a[x1,y1]:=x
else
begin
for j:=y1 to y2 do
begin
a[x1,j]:=x;
inc(x);
end;
for i:=x1+1 to x2-1 do
begin
a[i,y2]:=x;
inc(x);
end;
for j:=y2 downto y1 do
begin
a[x2,j]:=x;
inc(x);
end;
for i:=x2-1 downto x1+1 do
begin
a[i,y1]:=x;
inc(x);
end;
inc(x1);
inc(y1);
dec(x2);
dec(y2);
if (x1<=x2) then dien(x1,y1,x2,y2,x);
end;
if k mod 2=1 then
for b:=1 to n do
for c:=1 to n do a[b,c]:=sqr(n)+1-a[b,c];
end;

bài 4:
{khaibao}
{nhap}
dem:=1;
repeat
ok:=true;
inc(dem);
dua:=dem;
dua:=dua-1;
for i:=1 to 5
begin
if (dua mod 5<>0) and (dua<5) then begin ok:=false;break;end;
dua:=dua-dua/5;
end;
dua:=dua-5;
if ok then if (dua mod 5<> 0) then ok:=false;
until ok;
{xuat (dem la so dua ban dau)}
Không giải thích nha nhức đầu lém rùi. Tui làm 2 bài thui mấy bài còn lại nhường cho mọi người thảo luận đó ^^!

anhem115
16-03-2008, 00:12
Ok men này, mình dùng hàm kiểm tra nguyên tố cùng nhau để tránh trường hợp 1/3,2/6,3/9 . . .(mất công loại bỏ), nguyên tố cùng nhau thì bảo đảm tính tối giản của phân số.còn mình gán vào mảng thực để so sánh cho nó dễ!

Còn bạn boysitinh thì cái ma trận mình chỉ tăng một biến j thôi, until j=n*n

Ai đó làm thử bài chia kẹo mà dùng vét cạn đi, xin thỉnh giáo!

boysitinh_vl
16-03-2008, 08:31
Còn bạn boysitinh thì cái ma trận mình chỉ tăng một biến j thôi, until j=n*n
hjx, mấy bài này cũng là đề thi học sinh giỏi của tỉnh mình nhưng tỉnh mình câu chia dừa khó hơn. Cái bài xoắn ốc đó mình làm theo cách giải chuẩn của tỉnh mình. Còn bạn muốn làm cách nào thì bạn làm vì có rất nhìu cách giải. Bài chia dừa của tỉnh mình cho nhập số người rồi tính chứ đâu có cố định là 5 người. Thân anhem115
Bài xoắn ốc mình còn 1 cách nữa là dùng như sau:
if n=1 then ...
else
for i:=0 to n-2 do
begin
for {điền qua phải đầu+i to đuôi-i}
for {điền xuống đầu+1+i to đuôi-1-i}
if (n<3) or (i<>n-2) then for {điền qua trái đầu-i downto đuôi+i}
for {điền lên đầu-1 downto đuôi+1}
end;
{Nhưng 4 thì điền 2 lần nhưng n-1=3 vì lần cuối không có điền vào ô nào hết, tương tự với >5}
vd: n=2
thì số lần điền =1
for {điền qua phải đầu+i to đuôi-i} 1 to 2
1 2
0 0
for {điền xuống đầu+1+i to đuôi-1-i} 2 to 1 {không chạy}
1 2
0 0
if (n<3) or (i<>n-2) then for {điền qua trái đầu-i downto đuôi+i} 2 down to 1
1 2
4 3
for {điền lên đầu-1 downto đuôi+1} 1 downto 2 {không chạy}
1 2
4 3
xong hết rùi dùng cai này để xếp tăng hay giảm
if k mod 2=1 then
for b:=1 to n do
for c:=1 to n do a[b,c]:=sqr(n)+1-a[b,c];

anhem115
16-03-2008, 09:16
to boysitinh: hợp tác hữu nghị bình đẳng :D
còn bài tính ngày thì ta tách ngày tháng năm --> record-->tạo một hàm tính ngày(ứng với '03' là 31 ngày v.v . . ) sau đó ta tính độ chêng lệch giữa chúng như sau:
Trường hợp từ tháng 4/2007-->2/2008 thì ta lấy 2+(12-4)=8 tháng
tương tự đối với trường hợp ngày.



Hú Hú HÚ, có ai có đề thi học sinh giỏi tỉnh khánh hoà năm 2005-2006 của lớp 12 không, chia sẻ với.

okmen910
16-03-2008, 09:18
bài 3 em giải thế này có được không:

uses crt;
var a,b:array[1..100] of integer;
c,d:array[1..100] of real;
i,j,k,n,m,l:integer;
so:real;
kt:boolean;
{-----------------}
procedure dc(var a1,a2,b1,b2:integer;var c1,c2:real);
var tam:integer;tam1:real;
begin
tam:=a1;
a1:=a2;
a2:=tam;
tam:=b1;
b1:=b2;
b2:=tam;
tam1:=c1;
c1:=c2;
c2:=tam1;
end;
{------------}
begin
clrscr;
write('Nhap N:');readln(n);
k:=0;
m:=0;
for i:=0 to n do
for j:=1 to n do
begin
kt:=true;
inc(m);
so:=i/j;
d[m]:=so;
for l:=1 to m do
if (l<>m) and (so=d[l]) then kt:=false;
if (so<=1) and kt then
begin
inc(k);
c[k]:=so;
a[k]:=i;
b[k]:=j;
end;
end;
for i:=1 to k-1 do
for j:=i+1 to k do
if c[i]>c[j] then
dc(a[i],a[j],b[i],b[j],c[i],c[j]);
writeln;
write('F(',n,'):');
for i:=1 to k do write(a[i],'/',b[i],' ');
writeln;
writeln;
writeln('Tat ca co ',k,' phan so');
readln;
end.
<<nếu có chỗ nào dài dòng thì mọi người chỉ giúp>>

okmen910
16-03-2008, 09:25
ah` bạn anhem115 tên gì nhỉ, có gì đi thi thì mình biết mặt luôn

boysitinh_vl
16-03-2008, 09:34
bài 3 em giải thế này có được không:

uses crt;
var a,b:array[1..100] of integer;
c,d:array[1..100] of real;
i,j,k,n,m,l:integer;
so:real;
kt:boolean;
{-----------------}
procedure dc(var a1,a2,b1,b2:integer;var c1,c2:real);
var tam:integer;tam1:real;
begin
tam:=a1;
a1:=a2;
a2:=tam;
tam:=b1;
b1:=b2;
b2:=tam;
tam1:=c1;
c1:=c2;
c2:=tam1;
end;
{------------}
begin
clrscr;
write('Nhap N:');readln(n);
k:=0;
m:=0;
for i:=0 to n do
for j:=1 to n do
begin
kt:=true;
inc(m);
so:=i/j;
d[m]:=so;
for l:=1 to m do
if (l<>m) and (so=d[l]) then kt:=false;
if (so<=1) and kt then
begin
inc(k);
c[k]:=so;
a[k]:=i;
b[k]:=j;
end;
end;
for i:=1 to k-1 do
for j:=i+1 to k do
if c[i]>c[j] then
dc(a[i],a[j],b[i],b[j],c[i],c[j]);
writeln;
write('F(',n,'):');
for i:=1 to k do write(a[i],'/',b[i],' ');
writeln;
writeln;
writeln('Tat ca co ',k,' phan so');
readln;
end.
<<nếu có chỗ nào dài dòng thì mọi người chỉ giúp>>

Giải cách này sao tui test mới tới 10 là nó "die" rùi !!! Không bít pascal tui hư hay chương trình ông có vấn đề nữa. Đề bài yêu cầu 100 mà sao chạy được có 9 àh
bài này hình như tìm quy tắc thì phải
vd như:
n=9 thì (9 / 2)=4.5
-> 2/9 sau 1/4
0/1<1/9<1/8<1/7<1/6<1/5<2/9<1/4<...
cứ như thế mà tìm quy tắc típ tui bận rùi nên ko thể làm típ
còn bài tính ngày thì sách bài tập tin học lớp 11 trang 118 có nhưng nhớ là phải bỏ bớt những thứ không cần thiết nhé. Vì chương trình đó không dùng để làm bài tập của bạn nhưng mà chỉ cần bỏ những thứ không cần thiết là sẽ ra.

okmen910
16-03-2008, 09:46
có lẽ chương trình của em có vấn đề, chỗ khai báo mãng đổi lại 100 thành 999

boysitinh_vl
16-03-2008, 09:56
có lẽ chương trình của em có vấn đề, chỗ khai báo mãng đổi lại 100 thành 999
sua thanh 2000 lun vẫn chay được ~40 à lên 45 "die"
mà đề bài yêu cầu tới 100 lận làm kiểu này nếu 10 điểm thì dc 4 điểm đối với vòng tỉnh nha
Vòng tỉnh thi cũng dễ lắm ko khó đâu đừng suy nghĩ gì cao xa là ok thôi
Khj đi nhớ mang theo si-gum để vô ko bít gì hết thì nhai đỡ bùn ^^!

okmen910
16-03-2008, 10:29
nếu thế thì khỏi dùng c với d vậy, đàu tiên là tối giản i với j nếu i không bằng các số trong mãng a và j không bằng các số trong mãng b thì gán a[k]=i và b[k]=j

boysitinh_vl
16-03-2008, 11:10
nếu thế thì khỏi dùng c với d vậy, đàu tiên là tối giản i với j nếu i không bằng các số trong mãng a và j không bằng các số trong mãng b thì gán a[k]=i và b[k]=j
Bạn nên xem kỉ lại kiểu dữ liêu. Dễ chết lắm đó làm kiểu này là làm liều ^^!. Tốt nhất là làm ra qui tắc để chạy được những số lớn không có bài toán nào mà không có quy tắc để làm. Chịu khó suy nghĩ theo hướng khác sẽ tốt hơn
Thân okmen910

anhem115
16-03-2008, 13:02
Mình học lớp 12 rồi
tên mình hả
var x:string;
begin
x:='anhem115'
write('tên mình là :',copy(x,1,3));
readln;
end.

Cái bài phân số coi bộ hơi gay nha, chắc phải dùng cách mà 4 rum đề cập tới. nếu chơi theo kiểu suy nghĩ bình thường thì máy sẽ không chạy nổi tới số lớn. Thi tỉnh nó có ra đệ qui không zậy?

m2mpro
16-03-2008, 13:59
Bài phân số có lẽ cứ for mà giải xem sao :D
Cứ for từ 0->9 rồi một vòng nữa từ 1->9, lấy hai cái chia ra rồi in ra :D

boysitinh_vl
16-03-2008, 14:13
Bài phân số có lẽ cứ for mà giải xem sao :D
Cứ for từ 0->9 rồi một vòng nữa từ 1->9, lấy hai cái chia ra rồi in ra :D
ra thì ra nhưng sai , kakakakaka :)
Để chừng nào tui rãnh thì nghĩ phụ cho bây giờ đang làm mấy bài kia

okmen910
18-03-2008, 15:46
nếu lớn quá thì dùng mãng hai chiều để lưu (dẫu sao cũng tới 100 là hết)

boysitinh_vl
18-03-2008, 17:36
nếu lớn quá thì dùng mãng hai chiều để lưu (dẫu sao cũng tới 100 là hết)
hjx 2 chiều 1 chiều cũng zậy àh.
vd:
max của 1 chiều [1..40000] of byte
max của 2 chiều [1..200,1..200] of byte
200*200=40000
cũng có bao nhiu đó àh

anhem115
18-03-2008, 18:22
Các bạn làm bài được không, mình hi vọng được khuyến khích thôi làm được hơn một nửa à.
Cái bài phân số có cách làm như thế này. giả sử 3 phân số liêntiếp là t1/m1,
t2/m2,
t3/m3; thì ta có
t3=v*t2-t1;
m3=v*m2-m1;
với v=(m1+N) div m2;
như thế chỉ cần dùng một lần repeat là ra không cần mảng
với t1/m1:=0/1.t2/m2:=1/N--> t3/m3--> . . . .

Đề thi tỉnh lớp 12 lần này 2 bài đầu thì dễ, còn 2 bài sau thì một bài đệ qui một là quy hoạch động(không ôn nên không biết làm :D).

anhem115
18-03-2008, 18:29
bài thứ 3:
sinh ra dãy S = các kí tự A,B,C sao cho
-length(s)=100;
-không có 2 chuỗi conlientiếp nào giống nhau
-số kí tự B là ít nhất;

Bài 4
cho dãy số A1,.....,An
ta định nghĩa tổ hợp là tổng của A1.B1+A2.B2+....+An.Bn=S;
cho dữ liệu vào dòng 1 là 2 số :n và S
dòng 2 là dãy A1,...,An
--> xuất ra dãy số B1,...,Bn
điều kiện
B1,...,Bn là các số nguyên không âm
0<=Ai<=255 với mọi i
sao cho (B1+...+Bn) min

Ví dụ
vao.inp xuat.out
5 56 0 1 2 0 2
1 2 7 10 20