Giúp chỉ ra lỗi sai bài tập

Em có bài tập tìm khoảng cách giữa 2 nhà gần nhất. Tuy nhiên có một test case sai, em nghĩ là do out of bounds nhưng không biết sai ở đâu.

Đầu bài:

Input:

  • n (số ngôi nhà, 2<=n<=10^5)
  • n dòng sau là vị trí căn nhà (0<= ai<= 10^9)

Output: số nguyên duy nhất cho biết khoảng cách giữa hai căn nhà gần nhau nhất

VD:
Output:
3
3 1 6
Input: 2

Code của em:

#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define f0(i,n) for(int i=0;i<n;++i)
#define f1(i,n) for(int i=1;i<=n;++i)
#define MOD (ll)(1e9 + 7)

int main(){
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n,minn=MOD,d=0;
    cin >> n;
    int a[n];
    f0(i,n)cin >> a[i];
    sort(a,a+n);
    f0(i,n-1){
        if (a[i+1]-a[i]<minn)
          minn=a[i+1]-a[i];
    }
    cout << minn;
	return 0;
}

Test case sai:

1st token differs - expected: ‘96’, found: ‘1000000007’

Chỗ sai này thì có lúc là 2147483647,1677148948, 483193061, 1000000007(minn ban đầu).
Mong các bác giúp em. Em cảm ơn.

1 Like

Nhìn chung mình thấy idea và implementation của bạn không có vấn đề gì. Bạn có thể post test case khiến bạn cho ra kết quả sai lên đây (nếu dài quá thì có thể lưu file và gửi link) để mọi người có thể debug được không?

4 Likes

Khai báo mảng dùng vector hoặc mảng động nha.
Cú pháp int a[n]; chỉ có bên C th, qua C++ là dính UB đấy. :v

5 Likes

em làm trên vnoi, nên là không biết test case như thế nào ạ :sweat_smile:

Mình submit ở một bài tương tự thì lại Accept nhỉ :v
NTUCoder (Độ xác thực thì chưa rõ, chỉ là mình thấy có bài này tương tự bài bạn up)

thầy mình cho test case riêng nên mình cũng không biết như thế nào :dizzy_face:

cảm ơn bạn, để mình tìm hiểu cách dùng mảng động và vector :frowning: khi nào được mình bảo nhé

1 Like

Số này là số nguyên tố và giá trị bằng 2^{31}-1 là số nguyên có dấu 4 byte lớn nhất.

Có thể thầy bạn cho test case vượt giới hạn đề bài đã cho rồi. 0<=ai<=10^{9}, trong đáp án có cả những số rất lớn (nằm ngoài 10^{9}), khi đó kết quả có thể luôn là 10^{9}+7.
Chưa rõ vì sao minn lại tăng, có thể giảm về số có dấu, sau đó vì lý do gì đó thành kiểu không dấu chăng!?:thinking:

2 Likes

đáp án đúng của test case này là 96 ạ. với cả em dùng cả long longunsigned long long rồi nhưng đều sai :sweat_smile:

Bạn đã xét trường hợp nếu n = 2 chưa?

P/s: Bạn quăng mảng a ra ngoài main() và khai báo tĩnh a[100000] xem.

3 Likes

thử đổi dòng int a[n]; thành int* a = new int[n]; hoặc int a[100000]; xem có còn gặp lỗi vậy nữa ko :V

3 Likes
  • Trường hợp n=2 em thử rồi, không sai ạ
  • Em đã quăng a[100000] ra ngoài và khai báo tĩnh, nhưng vẫn sai trường hợp đó

Theo em xem thì test đấy không sai, vì vẫn có người AC được ạ

em cout << n xem n nó bằng bao nhiêu
nếu n nhỏ thì cout << a[i] với i chạy từ 0 tới n-1 xem input đó là gì :face_with_monocle:

2 Likes

1 bước đơn giản em có thể làm bây giờ là bỏ hết macro đi, viết lại code một cách tường minh và submit lại xem sao.

2 Likes

em cũng thử cách này để biết rồi, không hiểu sau các test khác thì được nhưng riêng test đấy cho ra EOF

cách này cũng không khả thi ạ :sweat_smile:

Ý là có chạy được không chứ thay macro dễ mà :smiley:

2 Likes

vẫn sai test case đó ạ

Khởi tại minn = a[1] - a[0] xem có được không :kissing: (một cách tường minh thì khi chắc chắn có ít nhất 1 phần tử, ta luôn khởi tạo giá trị nhỏ nhất chính là giá trị đầu tiên).


Trong competitive programming, viết macro f0, f1 như thế kia rất nguy hiểm. Vẫn dùng f0, f1 ở trên nếu người dùng gọi:

f0(i,n?4:5)

thì bản chất vòng for sẽ là

for (int i = 0; i < n ? 4 : 5; i++)

và vòng for này không bao giờ kết thúc được, trong khi ý của ta lại là

for (int i = 0; i < (n ? 4 : 5); i++)

Do vậy, khi viết macro for thì người ta hay viết thêm 1 cặp ngoặc nữa, tất nhiên về mặt toán học thì (n)n giống nhau nhưng ta tránh được những chuyện ngoài ý muốn.

#define f0(i,n) for (int i = 0; i < (n); i++)

P/s: Có FA chứ đừng F0, F1 :cold_sweat:

5 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?