티스토리 뷰

#include <stdio.h> //전처리된 치환 함수들
#define swap(a,b) {int tmp=a; a=b; b=tmp;}
#define swapR(a,b,c,d) {int tmp=a;a=d;d=c;c=b;b=tmp;}
#define swapL(a,b,c,d) {int tmp=a;a=b;b=c;c=d;d=tmp;}

//0 1
//3 2
//ro : 0,1,2,3 clock 

//부분배열의 상태 
//vertical : default 0  (1)
//horizon : default 0 (1)

//pos 특정 index 자리에 처음 배열의 어떤 부분이 있는가? 

int main(void) {
	//입력
	int n,m,r,t;
	scanf("%d %d %d",&n,&m,&r);
	int arr[n][m],brr[n][m];
	for(int i=0; i<n; i++)
	 for(int j=0; j<m; j++)
	  scanf("%d",&arr[i][j]);
	//반전 상태변수들, 회전 상태변수, 4개의 구역이 어디로 가야하는지를 담는 배열
	int v=0,h=0, ro = 0, pos[4] = {0,1,2,3}; //0, 1, 2, 3 clock
	for(int i=0; i<r; i++) { //동작 처리하기
		scanf("%d",&t);
		if(t==1) {
			if(ro==0 || ro == 2) { //0도, 180도 라면 상하반전 그대로
				v ^= 1;
				swap(pos[0], pos[3]);
				swap(pos[1], pos[2]);
			} else { //90도 270도이므로 기본 0도 상태 관점에선 좌우반전을 하는 것과 같다
				h ^= 1;
				swap(pos[0], pos[1]);
				swap(pos[2], pos[3]);
			}
		}
		else if(t==2) {
			if(ro==0 || ro == 2) { //0도, 180도
				h ^= 1;
				swap(pos[0], pos[1]);
				swap(pos[2], pos[3]);
			} else { //90도 270도
				v^=1;
				swap(pos[0], pos[3]);
				swap(pos[1], pos[2]);
			} 
		}
		else if(t==3) {
			++ro;
			if(ro == 4) ro = 0;
		}
		else if(t==4) {
			--ro;
			if(ro == -1) ro = 3;
		}
		else if(t==5) {
			swapR(pos[0], pos[1], pos[2], pos[3]);
		}
		else if(t==6) {
			swapL(pos[0], pos[1], pos[2], pos[3]);
		}
	}
	//입력한 배열에서 반전과, 4개의 구역이 있어야 하는 곳을 고려하여 새로운 배열에 대입한다.
	int nh = n/2, mh = m/2, nv,mv;
	int bnv[4] = {0, 0, nh, nh}, bmv[4] = {0, mh, mh, 0};
	for(int i=0; i<4; i++) {
		if(pos[i] == 0) nv=mv=0;
		else if(pos[i] == 1) nv=0, mv = mh;
		else if(pos[i] == 2) nv=nh, mv = mh;
		else if(pos[i] == 3) nv=nh, mv=0;
		
		if(v==0 && h==0) {
			for(int j=0; j<nh; j++) {
				for(int k=0; k<mh; k++) {
					brr[j+bnv[i]][k+bmv[i]] = arr[j+nv][k+mv];
				}
			}
		}
		else if(v==0 && h==1) {
			for(int j=0; j<nh; j++) {
				for(int k=mh-1; k>=0; k--) {
					brr[j+bnv[i]][mh-1-k+bmv[i]] = arr[j+nv][k+mv];
				} 
			}
		}
		else if(v==1 && h==0) {
			for(int j=nh-1; j>=0; j--) {
				for(int k=0; k<mh; k++) {
					brr[nh-1-j+bnv[i]][k+bmv[i]] = arr[j+nv][k+mv];
				} 
			}
		}
		else if(v==1 && h==1) {
			for(int j=nh-1; j>=0; j--) {
				for(int k=mh-1; k>=0; k--) {
					brr[nh-1-j+bnv[i]][mh-1-k+bmv[i]] = arr[j+nv][k+mv];
				} 
			}
		}
	}
	//회전상태에 따른 출력
	if(ro == 0) {
		for(int i=0; i<n; i++) {
			for(int j=0; j<m; j++) printf("%d ", brr[i][j]);
			printf("\n");
		}
	}
	else if(ro == 1) {
		for(int i=0; i<m; i++) {
			for(int j=n-1; j>=0; j--) printf("%d ", brr[j][i]);
			printf("\n");
		}
	}
	else if(ro == 2) {
		for(int i=n-1; i>=0; i--) {
			for(int j=m-1; j>=0; j--) printf("%d ", brr[i][j]);
			printf("\n");
		}
	}
	else if(ro == 3) {
		for(int i=m-1; i>=0; i--) {
			for(int j=0; j<n; j++) printf("%d ", brr[j][i]);
			printf("\n");
		}
	}
}

 

풀이방법

1. 처음 입력받은 배열을 문제에 나온 것 처럼 4개의 구역으로 나누고, 이들이 출력때는 어디에 있어야 하는지를 담는 배열을 만듭니다.

2. 상하반전, 좌우반전을 해야하는지에 대한 변수 (0, 1) 그리고 회전상태에 대한 변수를 만듭니다. (0, 1, 2, 3 각각 0도 90도 180도 270도)

 

3. 3이 입력되면 회전상태에 대한변수를 증가시키고, 4이면 감소시켜줍니다 (0~3)

4. 1이 입력되면 상하반전 변수를 증가시키고, 2가 입력되면 좌우반전 변수를 증가시킵니다. 또한 상하반전 때는 4개의 구역을 아래처럼 치환해주며, 좌우반전 또한 아래처럼 치환해줍니다.

 

 

5. 주의할 점은 회전상태가 90도, 270도 인 경우, 좌우반전은 처음 0도 인 상태에서 상하반전과 같고, 상하반전은 처음 0도인 상태에서 좌우 반전과 같습니다. 즉 90도, 270도 라면 1을 하라 하면 2을 하는 것과 같고, 2을 하라하면 1을 하는 것과 같습니다.

6. 5 또는 6을 입력받는다면, 아래처럼 합니다.

7. 좌우반전 변수, 상하반전 변수, 그리고 4개의 구역이 어디 있는지를 나태내는 변수를 이용하여, 기본의 입력된 배열을 반전 (반전변수가 1이라면) 시키고, 4개의 구역이 어디에 있는지를 고려하여 새로운 배열에 저장합니다.

 

8. 이제 출력만이 남았습니다. 단 주의할 점은 회전 방향에 따라서 출력을 해주어야 합니다.!!!! 즉 0도 , 90도, 180도, 270도 회전 방향에 맞게 출력하도록 만들어야 합니다.

최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함