# Bài I. Tính tiền điện (6đ)
:::spoiler **Đề bài**
Hiện tại, tiền điện của các hộ dân sống tại Hà Nội đang được tính theo thang như sau:
1. Bậc 1 (0 đến 50 kWh): $1678$ đồng/kWh.
2. Bậc 2 (51 đến 100 kWh): $1734$ đồng/kWh.
3. Bậc 3 (101 đến 200 kWh): $2014$ đồng/kWh.
4. Bậc 4 (201 đến 300 kWh): $2536$ đồng/kWh.
5. Bậc 5 (301 đến 400 kWh): $2834$ đồng/kWh.
6. Bậc 6 (401 kWh trở lên): $2927$ đồng/kWh.
**Yêu cầu:**
Nhập vào số nguyên dương $N$ là số kWh mà gia đình bạn Lan đã sử dụng trong tháng 2 vừa qua. Hãy tính số tiền điện mà gia đình Lan cần phải trả.
**Dữ liệu vào từ bàn phím:**
Gồm một số duy nhất là số nguyên dương $N$ $(1 \le N \le 10^5)$
**Kết quả ghi ra màn hình:**
Ghi ra một số duy nhất là số tiền gia đình Lan phải trả tính theo đơn vị đồng.
**Ví dụ:**
| Input | Output | Giải thích |
| ----- | -------- | --------------------------- |
| `30` | `50340` | Vì $30*1678=50340$ |
| `89` | `151526` | Vì $50*1678+39*1734=151526$ |
:::
:::spoiler **Code 1 (Python)**
```python
N = int(input())
if N <= 50:
print(N*1678)
elif N <= 100:
print(50*1678 + (N-50)*1734)
elif N <= 200:
print(50*1678 + 50*1734 + (N-100)*2014)
elif N <= 300:
print(50*1678 + 50*1734 + 100*2014 + (N-200)*2536)
elif N <= 400:
print(50*1678 + 50*1734 + 100*2014 + 100*2536 + (N-300)*2834)
else:
print(50*1678 + 50*1734 + 100*2014 + 100*2536 + 100*2834 + (N-400)*2927)
```
:::
:::spoiler **Code 2 (Python)**
```python
N = int(input())
ans = 0
# Tiền bậc 1
x = min(50, N)
N -= x
ans += 1678 * x
# Tiền bậc 2
x = min(50, N)
N -= x
ans += 1734 * x
# Tiền bậc 3
x = min(100, N)
N -= x
ans += 2014 * x
# Tiền bậc 4
x = min(100, N)
N -= x
ans += 2536 * x
# Tiền bậc 5
x = min(100, x)
N -= x
ans += 2834 * x
# Tiền bậc 6
ans += 2927 * N
print(ans)
```
:::
# Bài II. Số khác nhau (6đ)
:::spoiler **Đề bài**
Nhập vào từ bàn phím số nguyên dương $N$. $N$ dòng tiếp theo mỗi dòng là một số nguyên dương $A_i$.
**Yêu cầu:**
Đưa ra số lượng số khác nhau trong $N$ số đã nhập.
**Dữ liệu vào từ bàn phím:**
- Dòng đầu tiên là số nguyên dương $N$ $(1 \le N \le 10^5)$;
- $N$ dòng tiếp theo mỗi dòng là một số nguyên dương $A_i$ $(1 \le A_i \le 10^9)$.
**Kết quả ghi ra màn hình:**
Ghi ra một số duy nhất là số lượng số khác nhau trong $N$ số đã nhập.
**Ví dụ:**
Input:
```
3
11
2
11
```
Output:
```
2
```
Giải thích:
2 số khác nhau trong dãy đã nhập là 2 và 11.
:::
:::spoiler **Code (Python)**
```python
N = int(input())
s = set()
for i in range(N):
x = int(input())
s.add(x)
print(len(s))
```
:::
:::spoiler **Code (C++)**
```cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int N;
cin >> N;
set<int> s;
for (int i = 0; i < N; ++i) {
int x;
cin >> x;
s.insert(x);
}
cout << s.size();
}
```
:::
# Bài III. Thực hiện phép toán (5đ)
:::spoiler **Đề bài**
Nhập vào từ bàn phím một biểu thức chỉ gồm các số nguyên và các phép toán cộng (+) hoặc trừ (-).
**Yêu cầu:**
Đưa ra kết quả của biểu thức.
**Dữ liệu vào từ bàn phím:**
Gồm một dòng duy nhất là biểu thức (độ dài không quá 100 kí tự).
**Kết quả ghi ra màn hình:**
Ghi ra một số duy nhất là kết quả của biểu thức.
**Ví dụ:**
| Input | Output |
| ------------ | ------ |
| `123+456` | `579` |
| `123-56+100` | `167` |
:::
:::spoiler **Code 1 (Python)**
``` python
s = input()
print(eval(s))
```
:::
:::spoiler **Code 2 (Python)**
```python
s = input()
# Lưu vị trí của dấu
sign = []
for i, c in enumerate(s):
if c in '-+':
sign.append(i)
# Lưu các số theo thứ tự
num = [int(s[:sign[0]])] # Lưu số đầu
for i in range(1, len(sign)):
l = sign[i-1] + 1
r = sign[i]
# số phải nằm giữa hai dấu, tức [l, r)
num.append(int(s[l:r]))
num.append(int(s[sign[-1]+1:])) # Lưu số cuối
ans = num[0]
for i in range(len(sign)):
# sign[i] là dấu đứng trước num[i+1]
if sign[i] == '+':
ans += num[i+1]
else:
ans -= num[i+1]
print(ans)
```
:::
# Bài IV. Dãy con (3đ)
:::spoiler **Đề bài**
Cho dãy số $A$ có $N$ phần tử và một số nguyên $K$.
**Yêu cầu**:
Tìm độ dài của đoạn con liên tiếp $[l, r]$ dài nhất mà tổng các phần tử $A[l]+A[l+1]+\ldots+A[r]$ chia hết cho $K$.
**Dữ liệu vào từ bàn phím:**
- Dòng đầu tiên là 2 số nguyên dương $N$ và $K$ $(1\le N\le10^5, 1\le K\le10^8)$;
- Dòng tiếp theo gồm $N$ số nguyên dương của dãy số $A$ $(1\le A_i \le 10^8)$.
**Kết quả ghi ra màn hình:**
Ghi ra một số duy nhất là độ dài lớn nhất của dãy con liên tiếp thỏa mãn yêu cầu.
**Ví dụ:**
Input:
```
5 3
1
2
3
4
5
```
Output:
```
5
```
Giải thích:
Có nhiều đoạn con có tổng chia hết cho 3:
- Đoạn từ $3$ đến $3$ có độ dài là $1$, tổng là $3$
- Đoạn từ $1$ đến $2$ có độ dài là $2$, tổng là $3$
- Đoạn từ $4$ đến $5$ có độ dài là $2$, tổng là $9$
- Đoạn từ $1$ đến $3$ có độ dài là $3$, tổng là $6$
- Đoạn từ $2$ đến $4$ có độ dài là $3$, tổng là $9$
- Đoạn từ $3$ đến $5$ có độ dài là $3$, tổng là $12$
- Đoạn từ $1$ đến $5$ có độ dài là $5$, tổng là $15$
Trong các đoạn đó thì đoạn con từ $1$ đến $5$ là đoạn có tổng chia hết cho $3$ dài nhất nên đưa ra kết quả là $5$.
**Giới hạn:**
- 60% số điểm tương ứng 60% số test có $N \le 100$;
- 20% số điểm tiếp theo tương ứng 20% số test có $100 < N \le 1000$;
- 20% số điểm còn lại không có $1000 < N \le 10^5$.
:::
:::spoiler **Cách làm**
### Subtask 1 và 2 $(N \le 1000)$
Đơn giản là duyệt từng đoạn con, nếu tổng của đoạn con ấy chia hết cho $K$ thì cập nhật đáp án (xem code để hiểu hơn).
### Subtask 3 $(N \le 10^5)$
Sử dụng prefix sum, với $p_i$ là tổng của $i$ phần tử đầu tiên của $a$. Khi đó, $a_l+\ldots+a_r=p_r-p_{l-1}$. Nếu $p_r-p_{l-1}$ chia hết cho $K$ thì dãy con từ $l$ đến $r$ có tổng chia hết cho $K$. Sử dụng tính chất modulo: $(x+y)\bmod k = (x \bmod k + y\bmod k) \bmod k$, ta có thể đặt $p_i = p_i \bmod k$. Khi đó, dãy con thoả mãn có $p_r-p_{l-1}=0$. Đề bài hỏi dãy con dài nhất nên ta sẽ lưu vị trí xuất hiện đầu tiên và cuối cùng của từng phần tử trong prefix sum $p$.
:::
:::spoiler **Code sub 1, 2 (Python)**
``` python
n, k = map(int, input().split())
ans = 0
for l in range(n):
s = 0
for r in range(l, n):
s += a[r]
if s % k == 0:
ans = max(ans, r-l+1)
print(ans)
```
:::
:::spoiler **Code (C++)**
```cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
int s = 0;
map<int, pair<int, int>> mp; // lưu vị trí xuất hiện sớm nhất và muộn nhất
mp[0] = {0, -1};
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
s = (s + x) % k;
if (mp.count(s)) {
mp[s].second = i;
} else {
mp[s] = {i, -1};
}
}
int ans = 0;
for (auto p : mp) {
int l = p.second.first;
int r = p.second.second;
if (r == -1) {
continue;
}
ans = max(ans, r-l+1);
}
cout << ans;
}
```
:::
:::spoiler **Code (Python)**
```python
n, k = map(int, input().split())
s = 0
d = {0: [0, -1]}
for i in range(1, n+1):
s = (s + int(input())) % k
if s in d:
d[s][1] = i
else:
d[s] = [i, -1]
ans = 0
for l, r in d.values():
if r == -1:
continue
ans = max(ans, r-l+1)
print(ans)
```
:::