

Hãy luôn nhớ cảm ơn và vote 5*
nếu câu trả lời hữu ích nhé!
Đáp án:#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Mảng hướng để kiểm tra 4 ô kề cạnh (Trái, Phải, Trên, Dưới)
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};
void solve(int test_num) {
int n;
cin >> n;
vector<string> grid(n);
for (int i = 0; i < n; ++i) {
cin >> grid[i];
}
// Duyệt qua từng ô theo thứ tự hàng và cột
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
// Nếu ô là ô trống, tìm chữ cái hợp lệ nhỏ nhất
if (grid[r][c] == '.') {
for (char ch = 'A'; ch <= 'Z'; ++ch) {
bool ok = true;
// Kiểm tra 4 ô xung quanh xem có bị trùng chữ cái không
for (int k = 0; k < 4; ++k) {
int nr = r + dx[k];
int nc = c + dy[k];
if (nr >= 0 && nr < n && nc >= 0 && nc < n) {
if (grid[nr][nc] == ch) {
ok = false;
break;
}
}
}
// Nếu hợp lệ thì gán ký tự ch và dừng tìm kiếm
if (ok) {
grid[r][c] = ch;
break;
}
}
}
}
}
// In kết quả cho test
cout << "Case " << test_num << ":\n";
for (int i = 0; i < n; ++i) {
cout << grid[i] << "\n";
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
if (cin >> t) {
for (int i = 1; i <= t; ++i) {
solve(i);
}
}
return 0;
}
Giải thích các bước giải:
Vì đề yêu cầu kết quả có thứ tự từ điển nhỏ nhất, ta có thể duyệt lần lượt từng ô $(i, j)$ từ trên xuống dưới, từ trái sang phải:
Nếu ô $(i, j)$ đã được điền sẵn chữ cái, ta giữ nguyên.
Nếu ô $(i, j)$ là ô trống ('.'), ta thử chọn ký tự nhỏ nhất có thể bắt đầu từ 'A', 'B', 'C',...
Ký tự hợp lệ chọn cho ô $(i, j)$ là ký tự khác với ký tự ở các ô chung cạnh đã có giá trị (ô bên trên $(i-1, j)$, ô bên dưới $(i+1, j)$, ô bên trái $(i, j-1)$, ô bên phải $(i, j+1)$).
Do quy luật thứ tự từ điển, việc chọn ký tự hợp lệ nhỏ nhất cho từng ô theo thứ tự đọc (từ trên xuống, trái sang phải) luôn cho ra kết quả tối ưu toàn cục.
Hãy giúp mọi người biết câu trả lời này thế nào?
#include <bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
freopen("ALPHABET.INP","r",stdin);
freopen("ALPHABET.OUT","w",stdout);
int m; cin >> m;
for (int k = 1; k <= m; k++){
cout << "Case " << k << ':' << '\n';
int n; cin >> n;
vector <string> s(n + 1); /// Dùng vector<string> để chứa ô vuông ban đầu
for (int i = 1; i <= n; i++){
cin >> s[i];
s[i] = '.' + s[i]; /// Để tránh lỗi chỉ số khi kiểm tra theo cột ở phía sau, thêm 1 cột nữa vào phía trước ô vuông
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
if (s[i][j] == '.'){
for (char c = 'A'; c <= 'Z'; c++){ /// Với mỗi kí tự là '.', điền thử lần lượt các chữ cái từ 'A' -> 'Z' theo điều kiện là không trùng với các vị trí liền kề
/// Kiểm tra thêm điều kiện để khi trừ thì chỉ số không bị lỗi ngoài mảng.
if (i > 1 && s[i-1][j] == c) continue;
if (i < n && s[i+1][j] == c) continue;
if (j > 1 && s[i][j-1] == c) continue;
if (j < n && s[i][j+1] == c) continue;
s[i][j] = c;
break;
}
}
cout << s[i][j];
}
cout << '\n';
}
}
}
Hãy giúp mọi người biết câu trả lời này thế nào?
Bảng tin