Nash Matrix

Nash Matrix

Created by LXC on Thu Feb 29 10:07:14 2024

https://codeforces.com/problemset/problem/1316/D

ranting: 2000

tag: constructive algorithms, dfs and similar, graphs, implementation

problem

有一种用 $n \times n$ 的网格玩的游戏。

  • 当 $(i,j)$ 填的是 L 时,你会走到 $(i, j - 1)$;
  • 当 $(i,j)$ 填的是 R 时,你会走到 $(i, j + 1)$;
  • 当 $(i,j)$ 填的是 U 时,你会走到 $(i - 1, j )$;
  • 当 $(i,j)$ 填的是 D 时,你会走到 $(i + 1, j)$;
  • 当 $(i,j)$ 填的是 X 时,你将不动。

当你从 $(i, j)$ 出发,最后将会停止在 $(x_{(i, j)}, y_{(i, j)})$。或者,如果你永远不会停止,$(x_{(i, j)}, y_{(i, j)})$ 是 $(-1, -1)$。

现在给出所有的 $(x_{(i, j)}, y_{(i, j)})$,试构造出原网格。如果无法构造,输出 INVALID,否则输出 VALID,并输出一种合法网格。

solution

对于所走向目标非(-1,-1)的(i,j),我们将从(i,j)开始广搜,检查是否所有走向目标为(i,j)的下标都能与(i,j)连通。

对于走向目标为(-1,-1)的位置,我们检测周边是否有(-1-1),若有,则可以将这两个点设为”相互走向”,形成循环。然后对于包含了这两个点的(-1,-1)连通块都可以走向这两个点。

code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

#include <bits/stdc++.h>
#define SINGLE_INPUT
#define ll long long
#define ull unsigned long long
#define N 500005
#define MOD 998244353
using namespace std;

template<class t,class u> ostream& operator<<(ostream& os,const pair<t,u>& p) {
return os<<'['<<p.first<<", "<<p.second<<']';
}
template<class t> ostream& operator<<(ostream& os,const vector<t>& v) {
os<<'['; int s = 1;
for(auto e:v) { if (s) s = 0; else os << ", "; os << e; }
return os<<']';
}
template<class t,class u> ostream& operator<<(ostream& os,const map<t,u>& mp){
os<<'{'; int s = 1;
for(auto [x,y]:mp) { if (s) s = 0; else os << ", "; os<<x<<": "<<y; }
return os<<'}';
}

void sol() {
// cout << string(2, '#');
string d = "ULDR";
int n;
cin >> n;
vector<string> g(n+1, string(n+1, '#'));
vector<vector<pair<int,int>>> p(n+1, vector<pair<int,int>>(n+1));
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
cin >> p[i][j].first >> p[i][j].second;
}
}
vector<vector<int>> vis(n+1, vector<int>(n+1));
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
auto [x, y] = p[i][j];
if (x == i && j == y) {
g[i][j] = 'X';
// cout << "xx " << i << " " << j << endl;
queue<pair<int,int>> q;
q.emplace(i,j);
vis[i][j] = 1;
while (q.size()) {
auto [u,v] = q.front(); q.pop();
// cout << u << " " << v << endl;
for (int c=0; c<4; c++) {
int mu = u+(c-1)%2;
int mv = v+(c-2)%2;
if (0<mu && mu <= n && 0<mv && mv <= n && vis[mu][mv] == 0 && p[mu][mv] == pair<int,int>{i,j}) {
vis[mu][mv] = 1;
g[mu][mv] = d[(c+2)%4];
q.emplace(mu,mv);
}
}

}
}
}
}
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
if (g[i][j] == '#' && p[i][j].first != -1) {
cout << "INVALID\n";
return ;
}
}
}
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
if (g[i][j] == '#') {
queue<pair<int,int>> q;
for (int c=0; c<4; c++) {
int x = i, y = j;
int mx = x+(c-1)%2;
int my = y+(c-2)%2;
if (mx<=0 || mx>n || my<=0 || my>n || g[mx][my] != '#') continue;
vis[x][y] = 1;
vis[mx][my] = 1;
g[x][y] = d[c];
g[mx][my] = d[(c+2)%4];
q.emplace(x, y);
q.emplace(mx, my);
break;
}
if (q.empty()) {
cout << "INVALID\n";
return ;
}
while (q.size()) {
auto [x, y] = q.front(); q.pop();
for (int i=0; i<4; i++) {
int mx = x+(i-1)%2;
int my = y+(i-2)%2;
if (mx<=0 || mx>n || my<=0 || my>n || g[mx][my] != '#') continue;
g[mx][my] = d[(i+2)%4];
vis[mx][my] = 1;
q.emplace(mx, my);
}
}
}
}
}
// cout << vis << endl;
// cout << g << endl;
cout << "VALID\n";
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
cout << g[i][j];
}
cout << "\n";
}
}

int main() {
cout << setprecision(15) << fixed;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifndef SINGLE_INPUT
int t;
cin >> t;
while (t--) {
sol();
}
#else
sol();
#endif
return 0;
}