Hướng dẫn cho CANDY BOXES


Chỉ sử dụng khi thực sự cần thiết như một cách tôn trọng tác giả và người viết hướng dẫn này.

Chép code từ bài hướng dẫn để nộp bài là hành vi có thể dẫn đến khóa tài khoản.

Authors: Who_you_knows_Who

Spoiler Alert


Hình ảnh minh họa thuật toán:


Hint 1: < Cày trâu >

  • Vì các viên kẹo được đánh số 1, 2, ... nên ta có thể đơn giản hóa bài toán như sau:
  • k là số viên kẹo.
  • Bỏ kẹo lần lượt vào các hộp kẹo từ 1 -> n đến khi kẹo hết.
  • Thứ tự của hộp kẹo cuối cùng được bỏ sẽ là kết quả.
    if(k > a[i]) k -= a[i];
    else {
    cout << i << endl;
    break;
    }
    Full Code
    | O(N * Q) | 70% - 80% Test | TLE
    #include<bits/stdc++.h>
    using namespace std;
    long long a[1000000];
    int main ()
    {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    long long n, q, k;
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    cin >> q;
    while(q --)
    {
    cin >> k;
    for(int i = 1; i <= n; i ++)
    {
    if (k > a[i]) k -= a[i];
    else
    {
    cout << i << endl;
    break;
    }
    }
    }
    }

Hint 2: < Chặt nhị phân >
- Tương tự việc bỏ kẹo vào các hộp kẹo như cày trâu.
- Tạo một mảng tổng lưu giá trị tổng số viên kẹo từ hộp kẹo thứ 1 -> i.
- Chặt nhị phân mảng tổng để tìm vị trí.

Nếu các bạn chưa biết thuật toán chặt nhị phân, các bạn có thể tham khảo: Tại đây.

Minh họa giữa chặt nhị phâncày trâu:

Full code
| O (Q * (log(2, N) | 100% Test | AC
#include<bits/stdc++.h>
using namespace std;
long long a[1000000];
long long s[1000000];
int main ()
{
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
long long n, q, k;
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i], s[i] = s[i - 1] + a[i];
cin >> q;
while(q --)
{
cin >> k;
long long l = 1, r = n;
while (l <= r)
{
long long g = (l + r) / 2;
if (k <= s[g]) r = g - 1;
else l = g + 1;
}
cout << l << endl;
}
}


Nếu các bạn có thắc mắc gì thì có thể ib riêng cho mình: Tại đây



Bình luận

Không có bình luận nào.