AtCoder ABC 018 A&B&C AtCoder - 018
――For some reason, I didn't want to judge one by one, so I turned it in a loop --Keep the initial index and score --Sort by score --Replace the points with the order (index) --Sort by initial index --Output the replaced order
private void solveA() {
int[][] wk = new int[3][2];
for (int i = 0; i < 3; i++) {
wk[i] = new int[] { i, nextInt() };
}
Arrays.sort(wk, (x, y) -> -Integer.compare(x[1], y[1]));
for (int i = 0; i < 3; i++) {
wk[i][1] = i + 1;
}
Arrays.sort(wk, (x, y) -> Integer.compare(x[0], y[0]));
for (int[] is : wk) {
out.println(is[1]);
}
}
private void solveB() {
char[] wk = next().toCharArray();
int n = nextInt();
for (int i = 0; i < n; i++) {
int s = nextInt() - 1;
int e = nextInt() - 1;
while (s < e) {
wk[s] += wk[e];
wk[e] = (char) (wk[s] - wk[e]);
wk[s] = (char) (wk[s] - wk[e]);
s++;
e--;
}
}
out.println(new String(wk));
}
――The speed is slow, but I was able to AC. (At first, it was implemented in a loop, but it seems that TLE cannot be resolved, so I reconsidered it.)
――Is it just a problem statement? ?? ?? So when I actually entered the value in Excel, the following was found --Add $ (k-1) $ from the center to make a rhombus --The diamond must not contain a cross ――How many rhombuses can make the above conditions?
――It's slow because it does a full search, so I thought again if I could reduce the amount of search a little more. --The principle is how to find a safe zone for Minesweeper ――You have to search after all to fill in the numbers, but you can prun some of them, right?
Input example: 8 8 3 oooooooo oooooooo oooooooo oooooooo oxoooooo oooooooo oooooxoo oooxoooo
--Turn it into a table
o | o | o | o | o | o | o | o |
o | o | o | o | o | o | o | o |
o | o | o | o | o | o | o | o |
o | x | o | o | o | o | o | o |
o | o | o | o | o | o | o | o |
o | o | o | o | o | x | o | o |
o | o | o | x | o | o | o | o |
--K = 3, so x must not be within 3 from the center ――It is also NG to cross the wall --Enter a value with X = 3 / wall = 2
2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 2 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 2 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 2 |
2 | 3 | 0 | 0 | 0 | 0 | 0 | 2 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 2 |
2 | 0 | 0 | 0 | 0 | 3 | 0 | 2 |
2 | 2 | 2 | 3 | 2 | 2 | 2 | 2 |
――After that, put a value in the periphery and count the remaining 0s ――If you center the positions 1, 2 and 3, the wall will stick out or get caught in × --The 0 position can be the center
2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
2 | 1 | 1 | 1 | 1 | 1 | 1 | 2 |
2 | 1 | 0 | 0 | 0 | 0 | 1 | 2 |
2 | 2 | 1 | 0 | 0 | 0 | 1 | 2 |
2 | 3 | 2 | 1 | 0 | 1 | 1 | 2 |
2 | 2 | 1 | 1 | 1 | 2 | 1 | 2 |
2 | 1 | 1 | 2 | 2 | 3 | 2 | 2 |
2 | 2 | 2 | 3 | 2 | 2 | 2 | 2 |
--Remarks when TLE is resolved --TLE was resolved when continue was set to break when re-searching the surrounding area (the location is commented). ――I realized that I had to consider how to stop the search properly rather than continue.
private void solveC() {
int r = nextInt();
int c = nextInt();
int k = nextInt();
int[][] dist = new int[r][c];
for (int i = 0; i < r; i++) {
char[] wk = next().toCharArray();
for (int j = 0; j < c; j++) {
/*
*Since X is a land mine, max and others are 0 once
*/
if (wk[j] == 'x') {
dist[i][j] = k;
} else if (i == 0 || i == r - 1 || j == 0 || j == c - 1) {
/*
*Fill the one next to the wall
*/
dist[i][j] = k - 1;
} else {
dist[i][j] = 0;
}
}
}
/*
*Update the values at each location and check the safety zone
*/
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
/*
*If you are 0, you cannot distribute it to others
*safe area
*/
if (dist[i][j] == 0) {
continue;
}
allocateNum(r, c, dist, i, j);
}
}
long res = 0;
/*
*Count the number of safe zones
*/
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (dist[i][j] == 0) {
res++;
}
}
}
out.println(res);
}
private static final int[] dx = new int[] { 0, 0, 1, -1 };
private static final int[] dy = new int[] { 1, -1, 0, 0 };
private void allocateNum(int r, int c, int[][] dist, int i, int j) {
/*
*Distribute your value in all directions
*However, if there is already a value larger than the value calculated from your own value and distance, ignore it
*When distributing in all directions, you have to distribute it up to your own value, so double loop
*/
int base = dist[i][j];
for (int d4 = 0; d4 < 4; d4++) {
for (int dLen = 1; dLen <= base; dLen++) {
int wX = i + dx[d4] * dLen;
int wY = j + dy[d4] * dLen;
if (wX < 0 || r <= wX || wY < 0 || c <= wY || dist[wX][wY] >= base - dLen) {
/*
*Fixed continue to break (TLE resolved with this fix)
*Since we are looking from a place near the center, if there is a large value in the destination, there is no need to allocate any more
*/
// continue;
break;
}
/*
*As the distance increases, the allocation amount decreases by dLen.
*/
dist[wX][wY] = base - dLen;
//I updated the value so I will distribute it again
allocateNum(r, c, dist, wX, wY);
}
}
}
4 5 2 xoooo oooox ooooo oxxoo
UP side count
0 | 1 | 1 | 1 | 1 |
1 | 2 | 2 | 2 | 0 |
2 | 3 | 3 | 3 | 1 |
3 | 0 | 0 | 4 | 2 |
DOWN side count
0 | 3 | 3 | 4 | 1 |
3 | 2 | 2 | 3 | 0 |
2 | 1 | 1 | 2 | 2 |
1 | 0 | 0 | 1 | 1 |
private void solveC() {
int r = nextInt();
int c = nextInt();
int k = nextInt();
char[][] wk = new char[r][c];
for (int i = 0; i < r; i++) {
wk[i] = next().toCharArray();
}
int[][] up = new int[r][c];
int[][] down = new int[r][c];
for (int i = 0; i < c; i++) {
int uCnt = 0;
int dCnt = 0;
for (int j = 0; j < r; j++) {
if (wk[j][i] == 'o') {
uCnt++;
} else {
uCnt = 0;
}
if (wk[r - 1 - j][i] == 'o') {
dCnt++;
} else {
dCnt = 0;
}
up[j][i] = uCnt;
down[r - 1 - j][i] = dCnt;
}
}
long res = 0;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
/*
*Center confirmed
*However, if it is less than k in both the vertical direction, it cannot be the center.
*/
if (up[i][j] < k || down[i][j] < k) {
continue;
}
boolean canCnt = true;
/*
*Expand your search to the left and right
*/
for (int l = 1; l < k; l++) {
/*
*c is+Search in the direction of
* up/Both down satisfy the numerical value
*/
if (j + l >= c || up[i][j + l] < k - l || down[i][j + l] < k - l) {
canCnt = false;
break;
}
/*
*c is-Search in the direction of
* up/Both down satisfy the numerical value
*/
if (j - l < 0 || up[i][j - l] < k - l || down[i][j - l] < k - l) {
canCnt = false;
break;
}
}
if (canCnt) {
res++;
}
}
}
out.println(res);
}
-Look at whether $ (i, j) $ can be made into diamonds one by one. ――Of course, it's TLE, but you can manage to get only partial points. .. ..
private void solveC2() {
int r = nextInt();
int c = nextInt();
int k = nextInt();
char[][] wk = new char[r][c];
for (int i = 0; i < wk.length; i++) {
wk[i] = next().toCharArray();
}
long res = 0;
/*
*Both X-axis and Y-axis(k-1)Is necessary, so subtract that amount from the start and end
*/
for (int i = k - 1; i < r - (k - 1); i++) {
for (int j = k - 1; j < c - (k - 1); j++) {
if (chkBlack(wk, k, i, j, r, c)) {
res++;
}
}
}
out.println(res);
}
private boolean chkBlack(char[][] wk, int k, int i, int j, int r, int c) {
/*
*Left and right swing width is k-1
*/
int wkK = k - 1;
/*
*X axis
* -(k-1) - 0 - (k-1)
*/
for (int i2 = -wkK; i2 <= wkK; i2++) {
/*
*Y axis
* -(k-1)
* -
* 0
* -
* (k-1)
*/
for (int j2 = -wkK; j2 <= wkK; j2++) {
int x = i + i2;
int y = j + j2;
/*
*Narrow the search range to a rhombus
*/
if (Math.abs(i2) + Math.abs(j2) > wkK) {
continue;
}
/*
*Out if there is protrusion or black
*/
if (x < 0 || r <= x || y < 0 || c <= y || wk[x][y] == 'x') {
return false;
}
}
}
return true;
}
Recommended Posts