Hướng dẫn cho Bảng số


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: letangphuquy

Tutorial

Cần xác định:

  • Lưu bảng \(3 \times 3\) như thế nào?
  • Tính tổng như thế nào?
  • Làm sao để biết các số khác nhau?

Một vấn đề khác cần lưu tâm: Nếu cộng \(3\) số \(10^9\) thì tổng sẽ vượt quá giới hạn của kiểu int

Hướng 1: Dùng \(9\) biến

Solution
C++
#include<bits/stdc++.h>
using namespace std;

typedef long long Int;

int main()
{
    Int a,b,c,
        d,e,f,
        g,h,i;
    cin >> a >> b >> c 
        >> d >> e >> f 
        >> g >> h >> i;

    Int r1 = a + b + c;
    Int r2 = d + e + f;
    Int r3 = g + h + i;

    Int c1 = a + d + g;
    Int c2 = b + e + h;
    Int c3 = c + f + i;

    if (r2 == r1 && r3 == r2 && c1 == r1 && c2 == c1 && c3 == c2
        && (b != a || c != a || d != a || e != a || f != a || g != a || h != a || i != a))
        cout << "YES";
    else cout << "NO";
}
Review

Nhận xét: cách code trên mang tính lặp lại, và đoạn kiểm tra điều kiện hoặc tính tổng có khả năng cao bị nhầm (thừa hoặc thiếu).
Vì đã căn chỉnh khoảng cách để các biến trông giống dạng bảng nên đã đỡ nhầm hơn.

Hướng 2: Mỗi dòng là một mảng - 3 mảng cho 3 dòng

Solution
C++
#include<bits/stdc++.h>
using namespace std;

typedef long long Int;

int main()
{
    Int a[3], b[3], c[3];
    for (int i = 0; i < 3; i++) cin >> a[i];
    for (int i = 0; i < 3; i++) cin >> b[i];
    for (int i = 0; i < 3; i++) cin >> c[i];

    Int r1 = 0, r2 = 0, r3 = 0;
    for (int i = 0; i < 3; i++) {
        r1 += a[i]; 
        r2 += b[i];
        r3 += c[i];
    }

    Int c1 = a[0] + b[0] + c[0];
    Int c2 = a[1] + b[1] + c[1];
    Int c3 = a[2] + b[2] + c[2];

    bool diff = false;
    for (int i = 0; i < 3; i++) {
        if (a[i] != a[0]) diff = true;
        if (b[i] != a[0]) diff = true;
        if (c[i] != a[0]) diff = true;
    }


    if (r2 == r1 && r3 == r2 && c1 == r1 && c2 == c1 && c3 == c2
        && diff)
        cout << "YES";
    else cout << "NO";
}
Review

Nhờ dùng mảng, ta đã giảm lặp lại được bằng vòng for. Tuy nhiên, số kí tự cần gõ không ít hơn và việc tính tổng cột trở nên khó khăn.

Hướng 3: mảng hai chiều

C++
C++
#include<bits/stdc++.h>
using namespace std;

typedef long long Int;

int main()
{
    Int a[3][3], r[3] = {0}, c[3] = {0};
    bool differs = false;
    for (int i = 0; i < 3; i++) 
        for (int j = 0; j < 3; j++) {
            cin >> a[i][j];
            r[i] += a[i][j];
            c[j] += a[i][j];
            differs |= a[i][j] != a[0][0];
        }

    bool equals = true;
    for (int i = 0; i < 3; i++) {
        equals &= r[i] == r[0];
        equals &= c[i] == r[0];
    }

    if (equals && differs)
        cout << "YES";
    else cout << "NO";
}
Review

Cách làm này có code ngắn gọn, logic và khó bị nhầm lẫn hơn. Nếu muốn rõ ràng hơn, bạn có thể tách phần nhập cin >> a[i][j] với phần tính toán.

Bonus
Python
a = [[0] * 3] * 3

for i in range(3):
    a[i] = list(map(int, input().split()))

bằng = True
S = sum(a[0])
for i in range(3):
    bằng &= sum(a[i]) == S # tổng hàng thứ i = S

for j in range(3):
    bằng &= sum(a[:][j]) == S # tổng cột thứ j = S

khác = False
for i in range(3):
    for j in range(3):
        if a[i][j] != a[0][0]:
            khác = True

if bằng and khác: print('YES')


Bình luận


  • -8
    khoinguyentl2023    8:59 p.m. 23 Tháng 5, 2023

    Bình luận bị ẩn vì nhiều phản hồi tiêu cực. Nhấp vào đây để mở.