-
Notifications
You must be signed in to change notification settings - Fork 1
/
chess_nn.java
125 lines (113 loc) · 2.83 KB
/
chess_nn.java
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
import static java.util.Arrays.fill;
import java.io.*;
import java.util.*;
public class chess_nn {
static final String COLORS = "WB";
public static void main(String[] args) throws FileNotFoundException {
Scanner in = new Scanner(new File("chess.in"));
int n = in.nextInt();
int m = in.nextInt();
char[][] c = new char[n][m];
for (int i = 0; i < n; i++) {
c[i] = in.next().toCharArray();
}
Answer best = null;
for (int color = 0; color < 2; color++) {
Answer ans = solve(color, n, m, c);
if (best == null || ans.count < best.count) {
best = ans;
}
}
PrintWriter out = new PrintWriter("chess.out");
out.println(best.count);
for (String e : best.answers) {
out.println(e);
}
out.close();
}
static Answer solve(int color, int n, int m, char[][] c) {
int[] p1 = new int[n + m - 1];
int[] p2 = new int[n + m - 1];
fill(p1, -1);
fill(p2, -1);
boolean[] was = new boolean[n + m - 1];
int ans = 0;
for (int i = 0; i < n + m - 1; i++) {
fill(was, false);
if (dfs(i, c, color, p1, p2, was)) {
++ans;
}
}
String[] answer = new String[ans];
fill(was, false);
int count = 0;
for (int i = 0; i < n + m - 1; i++) {
if (p1[i] < 0) {
for (int j = 0; j < n + m - 1; j++) {
if (!hasEdge(i, j, c, color)) {
continue;
}
answer[count++] = getDiagonal2(j, n, m, color);
was[p2[j]] = true;
}
}
}
for (int i = 0; i < n + m - 1; i++) {
if (p1[i] >= 0 && !was[i]) {
answer[count++] = getDiagonal1(i, n, m, color);
}
}
return new Answer(ans, answer);
}
static String getDiagonal1(int sum, int n, int m, int color) {
int x = Math.min(sum, n - 1);
int y = sum - x;
return "1 " + (x + 1) + " " + (y + 1) + " "
+ COLORS.charAt((color ^ x ^ y) & 1);
}
static String getDiagonal2(int dif, int n, int m, int color) {
dif -= m - 1;
int x = Math.max(dif, 0);
int y = x - dif;
return "2 " + (x + 1) + " " + (y + 1) + " "
+ COLORS.charAt((color ^ x ^ y) & 1);
}
static boolean hasEdge(int sum, int dif, char[][] c, int color) {
dif -= c[0].length - 1;
if ((sum & 1) != (dif & 1)) {
return false;
}
int x = (sum + dif) / 2;
int y = (sum - dif) / 2;
if (x < 0 || x >= c.length || y < 0 || y >= c[x].length) {
return false;
}
return COLORS.indexOf(c[x][y]) != ((x ^ y ^ color) & 1);
}
static boolean dfs(int v, char[][] c, int color, int[] p1, int[] p2,
boolean[] was) {
if (was[v]) {
return false;
}
was[v] = true;
for (int i = 0; i < c.length + c[0].length; i++) {
if (!hasEdge(v, i, c, color)) {
continue;
}
if (p2[i] < 0 || dfs(p2[i], c, color, p1, p2, was)) {
p2[i] = v;
p1[v] = i;
return true;
}
}
return false;
}
static class Answer {
int count;
String[] answers;
public Answer(int count, String[] answers) {
this.count = count;
this.answers = answers;
}
}
}