코드굽는 타자기
SWEA[4615] - 재미있는 오셀로 게임[D3] 본문
링크
SWEA[4615]
문제설명
- 시뮬
문제풀이
- 시뮬
- 무조건 뒤집으면서 가면 안됨
- 못뒤집는 경우가 있음.
문제코드
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Solution {
public static int[][] dir = { //8방향 12시부터 시계방향
{-1,0},
{-1,1},
{0,1},
{1,1},
{1,0},
{1,-1},
{0,-1},
{-1,-1}
};
public static int[][] map;
public static int N;
public static boolean flipable(int r, int c,int dir_, int color) {
int nr=0;
int nc=0;
for (int i = 0; i < N-1; i++) { //암만 많이가봤자 N-1만큼밖에 못감
nr = r + dir[dir_][0];
nc = c + dir[dir_][1];
if(nr>=0 && nr<N && nc>=0 && nc<N) { //경계안에서
// 직선탐색중 끝까지 뒤집을 수 있도록해주는 돌이 없을 수 있음(벽을 만나거나, 빈칸이거나, 계속 다른색이거나)
if(map[nr][nc]==color) { //뒤집게 해 줄 돌을 찾았음
return true;
}
else if(map[nr][nc]==0) { //빈칸 일 경우
return false;
}
else { //다른 색일 경우
// 한칸이동
r = nr;
c = nc;
}
}
else { //경계 밖일 경우
return false;
}
}
// 뒤집을게없음
return false;
}
public static void flip(int r, int c, int dir_, int color) {
// 이 방향으로는 뒤집으면서 가면 된다.
int nr=0;
int nc=0;
for (int i = 0; i < N-1; i++) { //암만 많이가봤자 N-1만큼밖에 못감
nr = r + dir[dir_][0];
nc = c + dir[dir_][1];
if(map[nr][nc]==color) { //뒤집게 해 줄 돌을 찾았음
return;
}
else { //다른 색일 경우
// 색 바꾸고
map[nr][nc]=color;
// 한칸이동
r = nr;
c = nc;
}
}
}
public static void put(int r,int c,int color) {
// 돌 놓기
map[r][c]=color;
// 8방향으로 돌이 갈 수 있는지 없는지 탐색
for (int i = 0; i < 8; i++) {
// 1칸 탐색중 경계안에 있고, 빈칸이아니며, 다른색인 경우 직선탐색 시작한다.
// 직선탐색중 끝까지 뒤집을 수 있도록해주는 돌이 없을 수 있음(벽을 만나거나, 빈칸이거나, 계속 다른색이거나)
// 이러면 뒤집으면서가면 다시 되돌려줘야함. 미리 체크하고 뒤집기
if(flipable(r,c,i,color)) {
flip(r,c,i,color);
}
}
}
public static void main(String[] args) throws IOException {
//System.setIn(new FileInputStream("res/swea/4615.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int T=Integer.parseInt(br.readLine());
for (int test_case = 1; test_case <= T; test_case++) {
int W=0;
int B=0;
// 입력
st = new StringTokenizer(br.readLine().trim()," ");
N = Integer.parseInt(st.nextToken());
map = new int[N][N];
int M = Integer.parseInt(st.nextToken());
int[][] oper = new int[M][3]; //{c(y) , r(x), color}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine().trim()," ");
for (int j = 0; j < 3; j++) {
oper[i][j] = Integer.parseInt(st.nextToken());
}
}
// {1:흑, 2:백}
// 말 초기판 설정
map[(N/2)-1][(N/2)-1]=2;
map[(N/2)-1][(N/2)-1+1]=1;
map[(N/2)-1+1][(N/2)-1]=1;
map[(N/2)-1+1][(N/2)-1+1]=2;
// 돌 놓기
for (int i = 0; i < M; i++) {
put(oper[i][1]-1,oper[i][0]-1,oper[i][2]);
}
// 돌 세기
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if(map[i][j]==2) {
W++;
}
else if(map[i][j]==1) {
B++;
}
}
}
System.out.println("#"+test_case+" "+B+" "+W);
/*
* 초기화
*/
}//end test_case
}//end main
}
틀렸던 문제코드
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.Buffer;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Solution {
/*
* 흑:1 백:2
*/
static int[][] map = new int [9][9];
static int N;
static int M;
public static int[][] dir = { //8방향 탐색
{-1,0},
{-1,1},
{0,1},
{1,1},
{1,0},
{1,-1},
{0,-1},
{-1,-1}
};
/*
* 그 방향으로 체크하고 뒤집는다
*/
public static void flip(int r, int c, int color, int dir_) {
//dir_ 방향으로 다음이 지금과 다른 색상임.
int sr = r; //시작
int sc = c;
int nr = 0; //다음
int nc = 0;
int fr = 0; //마지막
int fc = 0;
int cnt = 0;
while(true) {
nr = sr+dir[dir_][0];
nc = sc+dir[dir_][1];
if(nr>=1 && nr<=N && nc>=1 && nc<=N) { //경계 내에서
if(map[nr][nc]!= color) { //뒤집어야 할 애
sr=nr;
sc=nc;
cnt++;
}
else if (map[nr][nc]== 0) { //없음, 벽
return;
}
else { //여기까지 뒤집어야 함.
fr=nr;
fc=nc;
break;
}
}
else { //벽
return;
}
}
for (int i = 1; i <= cnt; i++) {
nr = r+i*dir[dir_][0];
nc = c+i*dir[dir_][1];
map[nr][nc]=color;
}
}
public static void main(String[] args) throws NumberFormatException, IOException {
//System.setIn(new FileInputStream("res/swea/4615.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T=Integer.parseInt(br.readLine().trim());
for (int test_case = 1; test_case <= T; test_case++) {
StringTokenizer st = new StringTokenizer(br.readLine().trim(), " ");
N=Integer.parseInt(st.nextToken());
M=Integer.parseInt(st.nextToken());
map[N/2][N/2] = 2;
map[N/2+1][N/2] = 1;
map[N/2][N/2+1] = 1;
map[N/2+1][N/2+1] = 2;
int [][] oper = new int[M][3];
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine().trim(), " ");
for (int j = 0; j < 3; j++) {
oper[i][j] = Integer.parseInt(st.nextToken());
}
}
int r=0;
int c=0;
int color=0;
int nr=0;
int nc=0;
for (int i = 0; i < M; i++) {
/*put*/
r=oper[i][1];
c=oper[i][0];
color=oper[i][2];
map[r][c] = color;
/*dir_check*/
for (int dir_ = 0; dir_ < 8; dir_++) {
nr = r+dir[dir_][0];
nc = c+dir[dir_][1];
if(nr>=1 && nr<=N && nc>=1 && nc<=N) { //경계 안에서
if(map[nr][nc]==color || map[nr][nc]==0) { //체크할 필요 없음
continue;
}
else { //뒤에 그 색이 또 나오면 뒤집기 가능
flip(r,c,color,dir_);
}
}
else { //경계 밖인 경우
continue;
}
}
}
int B=0;
int W=0;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if(map[i][j]==1) {
B++;
}
else if(map[i][j]==2) {
W++;
}
}
}
System.out.println("#"+test_case+" "+B+" "+W);
/*
* 초기화
*/
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
map[i][j]=0;
}
}
N=0;
M=0;
}//end test_case
}//end main
}//end class
아쉬운점
- 왜틀렸는지 모르겠음
- 테케가 좀 많았으면좋겠음
잘한점
- 왜맞았는지 모르겠음 논리는 똑같이 해서 썼는데...
'알고리즘 > Simulation' 카테고리의 다른 글
SWEA[1873] - 상호의 배틀필드[D3] (0) | 2020.02.12 |
---|---|
SWEA[4014] - 활주로 건설 (0) | 2020.02.09 |
SWEA[5653] - 줄기세포배양 (0) | 2020.02.08 |
SWEA[5644] - 무선 충전기 (1) | 2020.02.06 |
SWEA[1954] - 달팽이 숫자[D2] (0) | 2020.01.21 |
Comments