반응형
snowman95
코딩수련장
snowman95
전체 방문자
오늘
어제
  • 분류 전체보기 (229)
    • 앱테크 (3)
    • 옵시디언 (5)
    • 드라마, 영화 (1)
    • 개발자 이야기 (23)
    • 프로젝트 (10)
      • 프로젝트 방법론 (7)
      • 프로젝트 기록 (2)
      • Github (1)
    • 개발 지식 (0)
      • 디자인 패턴 (0)
    • 프론트엔드 개발 (5)
      • 테크트리 (2)
      • React.js (19)
      • ReactNative (2)
      • Next.js (6)
      • GraphQL (6)
      • 패키지 매니저 (2)
      • 라이브러리 (3)
      • 상태관리 라이브러리 (4)
      • Web 지식 (3)
      • HTML CSS (26)
      • Javascript (16)
      • 도구 (Tool) (3)
      • 성능 최적화 (1)
      • 디자인시스템 (0)
    • Python (53)
      • 모음집 (1)
      • 문법 (12)
      • 라이브러리 (15)
      • 알고리즘 (10)
      • 백준 문제풀이 (9)
      • 코딩테스트 (2)
      • 도구 (Tool) (3)
    • C++ (20)
      • 알고리즘 (6)
      • 삼성SW기출 (6)
      • 삼성 A형 (6)
    • 데이터사이언스 (1)
    • 인프라 (9)
      • 하드웨어 지식 (4)
      • Ansible (2)
      • Database (2)
      • 쉘스크립트 (1)
    • 주식 (0)
    • 취업 준비 (4)
      • 취업 이야기 (0)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • 공간복잡도
  • 면접
  • 삼성SW역량테스트
  • 나의 해방일지
  • 티스토리챌린지
  • nextjs
  • 알고리즘
  • 전공요약
  • 백준
  • 삼성SDS
  • 전공 요약 #데이터베이스
  • C++
  • 전공 요약 #운영체제
  • 오블완
  • Next.js #graphql #tailwind.css
  • GraphQL
  • 전공 요약 #네트워크
  • A형
  • 언어
  • 기계식키보드 #nuphy

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
snowman95

코딩수련장

C++/삼성SW기출

[백준 17822: 원판 돌리기] (C++)

2019. 10. 24. 15:22
728x90
반응형

삼성 SW 역량 테스트

https://www.acmicpc.net/workbook/view/1152

ㄴ원판 돌리기

          https://www.acmicpc.net/problem/17822

 

 

 

l 문제

 

1. 중심이 같은 원판들을 주어진 조건에 따라 회전시킨다.
2. 원판
원판은 반지름이 1부터 N까지 크기 순서대로 놓여있다. ( 1이 가장 위 )
3. 원판의 숫자
각의 원판에는 M개의 정수가 적혀있고, i번째 원판에 적힌 j번째 수의 위치는 (i, j)로 표현한다.
( x, y )는 ( x + 1, y ), ( x - 1, y ), ( x, y -1 ) ,( x, y + 1) 과 인접하다.
간단하게 동서남북 4방향으로 생각하면 된다.


주의할 점
y = 0 일 때 y - 1 위치는 -1이 아닌 M-1로
y = M-1일 때 y + 1 위치는 M이 아닌 0으로 해주어야 한다.


4. 회전 시키는 원판만 돌아가며, 정확하게 간격 만큼 돌아간다.
i번째 회전할때 사용하는 변수는 xi, di, ki이다.
번호가 xi의 배수인 원판을 di 방향으로 ki칸 회전시킨다.
( di = 0 : 시계 방향, di = 1 : 반시계 방향 )

 

 

l 입력

 

첫째 줄에 N, M, T이 주어진다.
둘째 줄부터 N개의 줄에 원판에 적힌 수가 주어진다. i번째 줄의 j번째 수는 (i, j)에 적힌 수를 의미한다.
다음 T개의 줄에 xi, di, ki가 주어진다.

 

 

l 출력

 

원판을 T번 회전시킨 후 원판에 적힌 수의 합을 출력한다.

 

 

l 풀이

 

조건에 따라 시뮬레이션 하면 된다.
오른쪽, 아래, 왼쪽, 위 ( {0,1}, {1,0}, {0,-1}, {-1,0} )
인접 검사 함수
{
   if       0번째 수 && 왼쪽 방향 : x = i, y = M-1
   else if M-1번째 수 && 오른쪽 방향 : x =i, y = 0
   else    방향에 따라
   범위 검사
}


시뮬레이션 함수
{
  1. 회전
  2. 인접한 수 찾아내기
  3. 인접한 수를 제거
  4. 인접한 수가 없는 경우 처리
}
인접한 수 찾기, 제거
모두 반복하면서 인접한 수를 찾으면 check 해 두고
check된 것들을 일괄적으로 제거하면 된다.


제거는 마음대로 구현하면 되는데
나는 제거된 수를 -1로 간주하여 -1로 변경해주었다.
문제에 실수할 수 있는 부분
1. 모든 원판의 수가 제거된 경우
sum / 0 으로 인해 런타임 에러가 발생할 수 있다.
따라서 모든 원판의 수가 제거된 경우를 꼭 검사해주어야 한다.


2. 평균


평균이 정수가 아니라 실수라고 생각하고 풀어야 한다.
avg = 22 / 6 = 3.6666
avg > 3 이므로 3은 4가 된다.
avg < 4 이므로 4는 3이 된다.


그렇다면 avg = 120 / 24 = 5.000 일 때 avg와 5를 비교한다면?
같은 경우에 대해서는 문제에 제시되어 있지 않으므로 별다른 처리를 하지 않는다.


 

 

l  코드

 

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int N, M, T, x, d, k, ans, deleted_cnt;
vector<vector<int>> board;
bool adj[51][50];
int dx[] = { 0, 1, 0, -1 };
int dy[] = { 1 ,0 ,-1, 0 };

bool is_adjacent(const int &i, const int &j, const int &r)
{
	int tx, ty;
	if (j == 0 && r == 2) tx = i, ty = M - 1;
	else if (j == M - 1 && r == 0) tx = i, ty = 0;
	else tx = i + dx[r], ty = j + dy[r];
	if (tx >= 1 && ty >= 0 && tx <= N && ty < M)
	{
		if (board[tx][ty] == -1) return false;
		if (board[i][j] == board[tx][ty])
		{
			adj[i][j] = true, adj[tx][ty] = true;
			return true;
		}
	}
	return false;
}
void simulation()
{
	register int i, j, r, c;
	double sum = 0.0;
	bool adjacent;

	// 1. 회전
	c = k % M;
	for (i = x; i <= N; i += x)
	{
		if (d) rotate(board[i].begin(), board[i].begin() + c, board[i].end());
		else rotate(board[i].rbegin(), board[i].rbegin() + c, board[i].rend());
	}

	// 2. 인접한 수 찾아내기
	adjacent = false;
	for (i = 1; i <= N; ++i)
	{
		for (j = 0; j < M; ++j)
		{
			if (board[i][j] == -1) continue;
			sum += board[i][j];

			for (r = 0; r < 4; ++r)
				if (is_adjacent(i, j, r))
					adjacent = true;
		}
	}
	// 3. 인접한 수를 제거
	if (adjacent)
	{
		for (i = 1; i <= N; ++i)
		{
			for (j = 0; j < M; ++j)
			{
				if (adj[i][j])
				{
					board[i][j] = -1;
					++deleted_cnt;
				}
				adj[i][j] = false;
			}
		}
		return;
	}

	if (deleted_cnt == M * N) return;
	// 4. 인접한 수가 없는 경우 처리
	sum /= (double)(N * M - deleted_cnt);
	for (i = 1; i <= N; ++i)
	{
		for (j = 0; j < M; ++j)
		{
			if (board[i][j] == -1) continue;
			if ((double)board[i][j] > sum) --board[i][j];
			else if((double)board[i][j] < sum) ++board[i][j];
		}
	}
}

int main()
{
	// freopen("input.txt", "r", stdin);
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin >> N >> M >> T;

	board.resize(N + 1, vector<int>(M));
	register int i, j;
	for (i = 1; i <= N; ++i)
		for (j = 0; j < M; ++j)
			cin >> board[i][j];

	for (i = 0; i < T; ++i)
	{
		cin >> x >> d >> k;
		simulation();
		if (deleted_cnt == M * N) break;
	}
	for (i = 1; i <= N; ++i)
		for (j = 0; j < M; ++j)
			if (board[i][j] != -1)
				ans += board[i][j];

	cout << ans;
	return 0;
}

 

반응형
저작자표시 동일조건 (새창열림)

'C++ > 삼성SW기출' 카테고리의 다른 글

[백준 17837: 새로운 게임 2] (C++)  (1) 2019.11.01
[백준 17780: 새로운 게임] (C++)  (0) 2019.10.28
[백준 17825: 주사위 윷놀이] (C++)  (0) 2019.10.26
[백준 17779: 게리맨더링 2] (C++)  (1) 2019.10.23
[백준 17143: 낚시왕] (C++)  (0) 2019.10.21
    'C++/삼성SW기출' 카테고리의 다른 글
    • [백준 17780: 새로운 게임] (C++)
    • [백준 17825: 주사위 윷놀이] (C++)
    • [백준 17779: 게리맨더링 2] (C++)
    • [백준 17143: 낚시왕] (C++)
    snowman95
    snowman95
    (17~19) Unity/Unreal Engine 게임 프로그래머 (20~21) System Administrator ___________ (22~) React 웹 프론트앤드 개발자 __________ 깃헙 : https://github.com/snowman95

    티스토리툴바