---
# System prepended metadata

title: 'Đề THT B - BRVT - 2018: Editorial'

---

# Đề THT B - BRVT - 2018: Editorial

>[!Note] Thông tin
>Sau đây là lời giải của Kỳ thi Tin học trẻ bảng B tỉnh Bà Rịa - Vũng Tàu năm học 2017 - 2018.
>
>**Bạn đọc có thể nộp và chấm bài (test tự sinh)** [TẠI ĐÂY](https://chuyentin-brvt.online/contest/algi_thtb_15_24).
>
>:::info
>Chuẩn bị bởi ==team Logica==, thuộc khuôn khổ dự án [**The Algitect (ALGI Project)**](https://www.facebook.com/algitect.project)
>:::

[toc]

## Bài 1: Đếm số tam giác (8 điểm)

### Tóm tắt đề bài

Cho $n-1$ điểm trên cạnh $AB$ và chia $AB$ thành $n$ phần bằng nhau. Tương tự với $AC$.

Nối các điểm trên cạnh $AB$ với điểm $C$ và các điểm trên cạnh $AC$ với điểm $B$.

**Yêu cầu:** Đếm số lượng tam giác được tạo ra chia dư cho $2018$.

:::danger
**Lưu ý:** Các tam giác không nhất thiết phải được tạo bởi điểm nằm trên cạnh $AB$, $AC$.
:::

**Dữ liệu đảm bảo:** $1 \le n \le 10^9$.

### Lời giải

>[!Tip] Nhận xét
>Vì các điểm được nối từ $B$ và $C$ nên các tam giác tạo được ==có đỉnh là $B$ hoặc $C$==.
>
>:::success
>Tách nhỏ bài toán thành đếm số tam giác có đỉnh $B$ hoặc $C$.
>:::

![image](https://hackmd.io/_uploads/SyWLVlq0Je.png)

Xét hình minh họa ở trên, với mỗi cặp đỉnh trên cạnh $AC$, ta tạo được một vùng (đánh dấu màu vàng). Trong vùng này, có $n$ đường cắt (đánh dấu bằng màu xanh), và mỗi đường cắt trên tạo được thành một tam giác mới.

Do đó, số tam giác có đỉnh $B$ là ==$C^2_{n+1} \times n$==.
> $C^k_n$ là tổ hợp chập $k$ của $n$ có công thức là $\frac{n!}{(n-k)!k!}$.
> 
> Ta lấy $C^2_{n+1}$ vì trên $AC$ có $n+1$ đỉnh.

Tương tự, số tam giác có đỉnh $C$ là ==$C^2_{n+1} \times n$==.

>[!Caution]
>Nếu cộng hai đáp án ở trên lại, thì ta đang tính trùng số lượng các tam giác có có đỉnh là cả $B$ và $C$.
>::: danger
>Số lượng tam giác bị trùng như vậy là ==$n^2$==.
>> **Giải thích:**
>> Số tam giác trùng là số cách chọn một đỉnh và ghép với $B, C$, tức là $n \times n$.
>> Khi $1$ cạnh từ $B$ và $1$ cạnh từ $C$ (không tính $BC$) giao nhau sẽ tạo ra $1$ đinh.
>:::

**Đáp án:** $C^2_{n+1} \times 2n - n^2 = n^3$.

**Độ phức tạp thời gian:** $O \left( 1 \right)$.

:::success
:::spoiler Code
```cpp = 1
#include <bits/stdc++.h>
using namespace std;

long long n;

int main() {
    cin >> n;
    n %= 2018;
    cout << (n * n * n) % 2018;
    
    return 0;
}
```
:::

## Bài 2: Hình vuông số (7 điểm)

### Tóm tắt đề bài

Cho ma trận có kích thước $n \times n$, các số được điển theo thứ tự xoắn ốc. 

**Yêu cầu:** Hãy tìm giá trị của ô $(i,j)$.

**Dữ liệu đảm bảo:**
- $2 \le N \le 10^4$.
- $1 \le i, j \le N$.

### Lời giải

Vì giới hạn nhỏ, ta thực hiện di chuyển trên bảng như đề miêu tả để tìm đến ô $(i, j)$.

Đặt hai biến $t_1$ và $t_2$ đại diện cho hai con trỏ đang duyệt theo vòng xoắn ốc của ma trận.

Dùng vòng lặp `while` để liên tục dịch các con trỏ đến các biên rồi thay đổi hướng của chúng. Kết thúc vòng lặp khi $t_1 = i$ và $t_2 = j$.

**Độ phức tạp thời gian:** $O \left( n^2 \right)$.

:::success
:::spoiler Code
```cpp=1
#include <bits/stdc++.h>
using namespace std;

int n;
int main() {
    cin >> n;
    int x, y;
    cin >> x >> y;
    int cnt = 1,t1 = 1,t2 = 1;
    
    int l = 0, r = 1, d = 0, u = 0;
    //Hướng di chuyển hiện tại của con trỏ
    
    int bl = 1, br = n, bu = 2, bd = n;
    //Biên trái, biên phải, biên trên, biên dưới
    
    while (t1 != x || t2 != y) {
        cnt++;
        if (r==1) {
            t2++;
            if (t2 == br) {
                d = 1;
                r = 0;
                br--;
            }
        }
        else if (d == 1) {
            t1++;
            if (t1 == bd) {
                l = 1;
                d = 0;
                bd--;
            }
        }
        else if (l == 1) {
            t2--;
            if (t2 == bl) {
                u = 1;
                l = 0;
                bl++;
            }
        }
        else if (u == 1) {
            t1--;
            if (t1 == bu) {
                r = 1;
                u = 0;
                bu++;
            }
        }

    }
    
    cout << cnt;
    
    return 0;
}
```
:::