Tin học Đề pascal nâng cao (HSG)

Hải Ham Học

Học sinh
Thành viên
24 Tháng sáu 2017
133
34
26
20
Bà Rịa - Vũng Tàu
thcs hòa hiệp

Attachments

  • upload_2019-11-26_16-23-21.png
    upload_2019-11-26_16-23-21.png
    288.2 KB · Đọc: 78
Last edited:

Nhật Hạ !

Học sinh chăm học
Thành viên
14 Tháng tư 2019
409
292
76
18
Quảng Nam
THCS Lê Quang Sung
Đay là bài 2 nha! Mình không để ý mấy điều kiện khi nhập vào... bạn thêm vào nha! Bạn chạy chương trình xem sao, mình chạy thì đúng rồi đó!
Mã:
Var c:array[1..100] of longint;
i,t,n,ss,s,k,d,j,dd: longint;
Begin
Write('Nhap so cay '); Readln(n);
For i:=1 to n do
        Begin
        write('c[',i,']=');
        Readln(c[i]);
        ENd;
For i:=1 to n do s:=s+c[i];
For i:=(n div 2) downto 2 do
        Begin
        If (s mod i = 0) then
                Begin
                ss:=s div i;
                For j:=1 to n do
                        Begin
                        If t<ss then t:=t+c[j];
                        If t=ss then
                                Begin
                                inc(d); t:=0;
                                If j=n then Begin k:=ss; dd:=d; End;
                                End;
                        If t>ss then Begin t:=0; break; end;
                        End;
                End;
        If j=n then break;
        End;
If d=0 then write(1) else write(dd,' ',k);
Readln;
End.
 

CuongGrove

Học sinh
Thành viên
29 Tháng mười 2019
83
36
21
20
Quảng Ngãi
THPT Trà Bồng
Mã:
Program BT1;
Uses crt;
Var n,i,k,j,bienKiemTra,bienThu,bienDem,bienSoLuong : longint;
    a : array [1..9999] of integer;
Begin
    Write('Hay nhap N : ');Readln(n);
    For i:= 1 to n do
        Begin
            Write('Hay nhap so thu ',i,' : ');Readln(a[i]);
        End;
    i:=0;
    Repeat
        Begin
            i:=i+1;
            bienDem :=1;
            bienKiemTra:=0;
            bienSoLuong:=0;
            For j:=1 to i do bienKiemTra:=bienKiemTra + a[j];
            For j:= i+1 to n do
                Begin
                    bienThu:=0;
                    For k:= i+1 to j do bienThu:= bienThu + a[k];
                    If bienKiemTra = bienThu then
                        Begin
                            bienDem:= bienDem + 1;
                            i:=j;
                            Writeln(i);
                            bienSoLuong := bienSoLuong + (j-k+1);
                        End;
                End;
        End;
    Until (i=n) or (bienSoLuong = n);   
    If bienDem =1 then Writeln('1')
    Else Write(bienDem,' ',bienKiemTra);
    Readln;

End.
Mình làm bài 1, mình cho chạy thì thấy đúng, còn bạn thì làm như thế nào? Up lên mình tham khảo với !
 
  • Like
Reactions: Hải Ham Học

Hải Ham Học

Học sinh
Thành viên
24 Tháng sáu 2017
133
34
26
20
Bà Rịa - Vũng Tàu
thcs hòa hiệp
Chết mình nhầm, cái này bài 2 :))))), bạn chủ thớt có làm đc bài 1 k?
Bài 2 : - Mình đang suy nghĩ theo 1 cách như vầy : cộng dồn hết N phần tử lại rồi dùng vòng for downto.. để tìm ra số chia hết cho cái tổng đó, rồi khi phát hiện chia hết thì sẽ tạo 1 vòng for con trong vòng for đó là đi phân chia từng đoạn ra bằng với tổng / chia cho số chia hết đó, nếu phát hiện cả hàng cây nó phân đoạn ra được hết thì break vòng lặp for "lớn" và in ra kết quả có đoạn phân chia đó(và cái gì đó nữa) còn không phát hiện thì tiếp tục cho đến khi i= 2 thì nó out vòng lặp for "lớn" rồi in ra số 1 (1 đây là chỉ phân ra 1 phân đoạn thôi)... tối mình sẽ viết code nếu đúng thì úp lên cũng tham khảo nhé!!
Bài 1 : - chắc để suy nghĩ sau, bạn cũng thử suy nghĩ cũng với mình đi.
 

Hải Ham Học

Học sinh
Thành viên
24 Tháng sáu 2017
133
34
26
20
Bà Rịa - Vũng Tàu
thcs hòa hiệp
Đay là bài 2 nha! Mình không để ý mấy điều kiện khi nhập vào... bạn thêm vào nha! Bạn chạy chương trình xem sao, mình chạy thì đúng rồi đó!
Mã:
Var c:array[1..100] of longint;
i,t,n,ss,s,k,d,j,dd: longint;
Begin
Write('Nhap so cay '); Readln(n);
For i:=1 to n do
        Begin
        write('c[',i,']=');
        Readln(c[i]);
        ENd;
For i:=1 to n do s:=s+c[i];
For i:=(n div 2) downto 2 do
        Begin
        If (s mod i = 0) then
                Begin
                ss:=s div i;
                For j:=1 to n do
                        Begin
                        If t<ss then t:=t+c[j];
                        If t=ss then
                                Begin
                                inc(d); t:=0;
                                If j=n then Begin k:=ss; dd:=d; End;
                                End;
                        If t>ss then Begin t:=0; break; end;
                        End;
                End;
        If j=n then break;
        End;
If d=0 then write(1) else write(dd,' ',k);
Readln;
End.
cho mình xin phép góp ý xíu nhaaa... là nếu cho vòng lặp chạy từ n div 2 ngược chiều về 2 thì nó sẽ không chính xác 100%, nếu vậy cho nó chạy từ s div 2 mình nghĩ sẽ đúng nhất, mà con set time tối giản nhất nữa
 

Hải Ham Học

Học sinh
Thành viên
24 Tháng sáu 2017
133
34
26
20
Bà Rịa - Vũng Tàu
thcs hòa hiệp
Mã:
Program BT1;
Uses crt;
Var n,i,k,j,bienKiemTra,bienThu,bienDem,bienSoLuong : longint;
    a : array [1..9999] of integer;
Begin
    Write('Hay nhap N : ');Readln(n);
    For i:= 1 to n do
        Begin
            Write('Hay nhap so thu ',i,' : ');Readln(a[i]);
        End;
    i:=0;
    Repeat
        Begin
            i:=i+1;
            bienDem :=1;
            bienKiemTra:=0;
            bienSoLuong:=0;
            For j:=1 to i do bienKiemTra:=bienKiemTra + a[j];
            For j:= i+1 to n do
                Begin
                    bienThu:=0;
                    For k:= i+1 to j do bienThu:= bienThu + a[k];
                    If bienKiemTra = bienThu then
                        Begin
                            bienDem:= bienDem + 1;
                            i:=j;
                            Writeln(i);
                            bienSoLuong := bienSoLuong + (j-k+1);
                        End;
                End;
        End;
    Until (i=n) or (bienSoLuong = n); 
    If bienDem =1 then Writeln('1')
    Else Write(bienDem,' ',bienKiemTra);
    Readln;

End.
Mình làm bài 1, mình cho chạy thì thấy đúng, còn bạn thì làm như thế nào? Up lên mình tham khảo với !
1 bài rất hay <3 Liệu bạn với mình có thể kb Facebook để trao đổi với nhau, mình rất thích bộ môn pascal (tin học) và đang ôn thi hsg
 
  • Like
Reactions: CuongGrove

Nhật Hạ !

Học sinh chăm học
Thành viên
14 Tháng tư 2019
409
292
76
18
Quảng Nam
THCS Lê Quang Sung
cho mình xin phép góp ý xíu nhaaa... là nếu cho vòng lặp chạy từ n div 2 ngược chiều về 2 thì nó sẽ không chính xác 100%, nếu vậy cho nó chạy từ s div 2 mình nghĩ sẽ đúng nhất, mà con set time tối giản nhất nữa
Mình nghĩ i chạy từ n div 2 thì tối giản nhất chứ bạn...
Trong trường hợp này i là số nhóm dự kiến sẽ chia, n là số phần tử, s là tổng của mảng, mà tổng của mảng thì có thể rất lớn trong khi số phần tử có thể nhỏ hơn nhiều.
Lấy ví dụ tổng = 30, mà số phần tử chỉ = 9, bạn chạy từ s div 2 nghĩa là chạy từ 15... chỉ có 9 cây mà chia sao được 15 nhóm nhỉ? Mình thấy phi lý quá, nếu chạy chương trình như này còn tốn thời gian hơn
 

Hải Ham Học

Học sinh
Thành viên
24 Tháng sáu 2017
133
34
26
20
Bà Rịa - Vũng Tàu
thcs hòa hiệp
Mình nghĩ i chạy từ n div 2 thì tối giản nhất chứ bạn...
Trong trường hợp này i là số nhóm dự kiến sẽ chia, n là số phần tử, s là tổng của mảng, mà tổng của mảng thì có thể rất lớn trong khi số phần tử có thể nhỏ hơn nhiều.
Lấy ví dụ tổng = 30, mà số phần tử chỉ = 9, bạn chạy từ s div 2 nghĩa là chạy từ 15... chỉ có 9 cây mà chia sao được 15 nhóm nhỉ? Mình thấy phi lý quá, nếu chạy chương trình như này còn tốn thời gian hơn
mình đang nghĩ đến trường hợp mà tổng của mẳng a lớn hơn rất nhiều so với N thì nó sẽ bị sót số để chia, với lại chưa chắc gì cái phân chia ra bào nhiêu phần nó đã phụ thuộc vào cái tổng mà nó phụ thuộc vào cách đặt vị trí của a nữa,...
Bạn hiểu ý mình nói chứ
 

Nhật Hạ !

Học sinh chăm học
Thành viên
14 Tháng tư 2019
409
292
76
18
Quảng Nam
THCS Lê Quang Sung
mình đang nghĩ đến trường hợp mà tổng của mẳng a lớn hơn rất nhiều so với N thì nó sẽ bị sót số để chia, với lại chưa chắc gì cái phân chia ra bào nhiêu phần nó đã phụ thuộc vào cái tổng mà nó phụ thuộc vào cách đặt vị trí của a nữa,...
Bạn hiểu ý mình nói chứ
À mình hiểu rồi, vậy bạn cho For i:=n-1 downto 2 do
Dù vị trí có đặt như thế nào, tổng có lớn bao nhiêu thì số nhóm chia được nhiều nhất vẫn chỉ bằng n-1 thôi nha.
 
Last edited:

CuongGrove

Học sinh
Thành viên
29 Tháng mười 2019
83
36
21
20
Quảng Ngãi
THPT Trà Bồng
À mà bài 1 ở ngoài đời thật mình cũng thấy khó nữa, giờ phải chỉ cho máy tính :)))))
Mà bài 3 đề mình đọc chả hiểu, ý là nếu có 3;8 và 3;6 thì bỏ đi 2 trường hợp này á hả ?
 

CuongGrove

Học sinh
Thành viên
29 Tháng mười 2019
83
36
21
20
Quảng Ngãi
THPT Trà Bồng
Bài 2 : - Mình đang suy nghĩ theo 1 cách như vầy : cộng dồn hết N phần tử lại rồi dùng vòng for downto.. để tìm ra số chia hết cho cái tổng đó, rồi khi phát hiện chia hết thì sẽ tạo 1 vòng for con trong vòng for đó là đi phân chia từng đoạn ra bằng với tổng / chia cho số chia hết đó, nếu phát hiện cả hàng cây nó phân đoạn ra được hết thì break vòng lặp for "lớn" và in ra kết quả có đoạn phân chia đó(và cái gì đó nữa) còn không phát hiện thì tiếp tục cho đến khi i= 2 thì nó out vòng lặp for "lớn" rồi in ra số 1 (1 đây là chỉ phân ra 1 phân đoạn thôi)... tối mình sẽ viết code nếu đúng thì úp lên cũng tham khảo nhé!!
Bài 1 : - chắc để suy nghĩ sau, bạn cũng thử suy nghĩ cũng với mình đi.
Mình nghĩ nếu làm theo cách của bạn thì máy tính nó chạy nhanh hơn đó, bạn up lên thử xem, mà nhớ thử với nhiều trường hợp khác nữa nhé, vd như 2 3 2 3 hay 3 4 5 2 chẳng hạn
 

Nhật Hạ !

Học sinh chăm học
Thành viên
14 Tháng tư 2019
409
292
76
18
Quảng Nam
THCS Lê Quang Sung
Đây là bài 1 nha... bạn chạy rồi tìm thử có trường hợp nào sai không, mình thì chưa thấy trường hợp sai.
Mã:
function dx(x:string): boolean;
        Var i,l: integer;
        Begin
        dx:=false; i:=1; l:=length(x)+1;
        While (x[i]=x[l-i]) and (i<=l div 2) do inc(i);
        If i>(l div 2) then dx:=true;
        End;
Var s,o:string; i,d:integer;
Begin
Write('Nhap sau ');Readln(s);
For i:=1 to length(s) do
if dx(s) then break
else
Begin
If (s[i]<>s[length(s)-i+1]) and (s[i]=s[length(s)-i]) then
        Begin
        o:=s[length(s)-i+1];
        insert(o,s,i);
        inc(d);
        End else
If (s[length(s)-i+1]<>s[i]) and (s[length(s)-i+1]=s[i+1]) then
        Begin
        o:=s[i];
        insert(o,s,length(s)-i+2);
        inc(d);
        End else
If s[i]<>s[length(s)-i+1] then
        Begin
        o:=s[i];
        insert(o,s,length(s)-i+2);
        inc(d);
        End;
End;
write(d);
Readln;
End.
Mình nghĩ nếu làm theo cách của bạn thì máy tính nó chạy nhanh hơn đó, bạn up lên thử xem, mà nhớ thử với nhiều trường hợp khác nữa nhé, vd như 2 3 2 3 hay 3 4 5 2 chẳng hạn
Cách bạn ấy nói là cách mà mình làm ở trên đó bạn.
 
Last edited:

Hải Ham Học

Học sinh
Thành viên
24 Tháng sáu 2017
133
34
26
20
Bà Rịa - Vũng Tàu
thcs hòa hiệp
À mình hiểu rồi, vậy bạn cho For i:=n-1 downto 2 do
Dù vị trí có đặt như thế nào, tổng có lớn bao nhiêu thì số nhóm chia được nhiều nhất vẫn chỉ bằng n-1 thôi nha.
để mình ví dụ cho dễ hiểu nhé .. nếu s của toàn bộ mảng a có tổng là 120 mà cái N =6 thì ...chẳng hạn đi cái dãy nó chia đều ra 2 phần mỗi phần 60 và cái dãy mảng a nó không thể chia ra theo từng phần khác nữa mà chỉ chia ra 2 phần mỗi phần 60 thôi.... thì nó sẽ bị sót trường hợp đó, mình không nói code bạn sai nhưng nó chưa đúng hoàn toàn nhé !!! thay đổi cái for đầu tiền là " for i:=s div 2 to n do.."
 

Nhật Hạ !

Học sinh chăm học
Thành viên
14 Tháng tư 2019
409
292
76
18
Quảng Nam
THCS Lê Quang Sung
Bài 1 mình sửa lại chút để xét mấy trường hợp đặc biệt nha bạn, bạn xem sai trường hợp nào thì báo lại nha.
Mã:
function dx(x:string): boolean;
        Var i,l: integer;
        Begin
        dx:=false; i:=1; l:=length(x)+1;
        While (x[i]=x[l-i]) and (i<=l div 2) do inc(i);
        If i>(l div 2) then dx:=true;
        End;
Var s,o,ss:string; i,d,dd:integer;
Begin
Write('Nhap sau ');Readln(s); ss:=s;
For i:=1 to length(s) do if dx(s) then break else
Begin
If (s[i]<>s[length(s)-i+1]) and (s[i]=s[length(s)-i]) then
        Begin
        o:=s[length(s)-i+1];
        insert(o,s,i);
        inc(d);
        End else
If s[i]<>s[length(s)-i+1] then
        Begin
        o:=s[i];
        insert(o,s,length(s)-i+2);
        inc(d);
        End;
End;
For i:=1 to length(ss) do
if dx(ss) then break
else
Begin
If (ss[length(ss)-i+1]<>ss[i]) and (ss[length(ss)-i+1]=ss[i+1]) then
        Begin
        o:=ss[i];
        insert(o,ss,length(ss)-i+2);
        inc(dd);
        End else
If ss[i]<>ss[length(ss)-i+1] then
        Begin
        o:=ss[length(ss)-i+1];
        insert(o,ss,i);
        inc(dd);
        End;
End;
If (dd<d) and (dd>0) then begin d:=dd; s:=ss; end;
write(s,' ',d);
Readln;
End.
Còn về bài 2 thì nếu để For i:=n-1 downto 2 do thì không bao giờ bỏ xót trường hợp bạn ví dụ đâu nhé, mà có để i:=n div 2 cũng không xót được, mình thử rồi nha nhưng nếu để chắc chắn nhất thì để i:=n-1 nhé! À với lại sau chỗ ss:=s div i; bạn gán thêm d:=0 nữa nhé~
 
  • Like
Reactions: Hải Ham Học
Top Bottom