int main(void) {
    int T;
    int n1, n2;
    int rep_mark[] = {1,1,4,4,2,1,1,4,4,2}; // 10, 1, ... , 9
    scanf("%d", &T);
    while(T--) {
		scanf("%d %d", &n1, &n2);
		if((n1%=10) == 0) 
		{
			printf("10\n");
			continue;
		}
		if(rep_mark[n1]==2) 
		{
			n2%=2; 
			if(n2==0) 
				n1 = (n1*n1)%10;	
		} else if(rep_mark[n1]==4) {
			switch(n2&3) {
				case 0:
					n1*=n1; n1*=n1;
					break;
				case 2:
					n1*=n1; break;
				case 3:
					n1 *= (n1*n1);
					break;
			}
			n1%=10;
		}
		printf("%d\n", n1);
	}
}

a^b % 10을 구하는 매우 간단한 문제이다.

하지만 b의 범위가 1,000,000 이하 까지 가능하기에 a^b를 직접한다는 것은 무모하다.

2^999 만 해도5357543035931336604742125245300009052807024058527668037218751941851755255624680612465991894078479290637973364587765734125935726428461570217992288787349287401967283887412115492710537302531185570938977091076523237491790970633699383779582771973038531457285598238843271083830214915826312193418602834034688

이렇게 높은 수가 나와 오버플로우를 일으키기 때문이다.


1 . 그래서 최대한 a^b를 직접하는건 제외한다.

그럼 어떻게 풀까

선배와 친구들의 풀이를 보았을때

나머지 연산은 결국 일의 자리만 보고 판단하기 때문에 mod 10을 한후 제곱하는 방식으로 푸는 것을 보았다.

하지만 굳이 그렇게 계속 계산할 필요가 없다는 것을 우리는 고등 교육까지 받으면서 알아왔다.


7 ^ 100의 1의자리는 7의 제곱수의 일의자리가 7 9 3 1 로 반복한다는 것을 이용하여 (7^4)^25 -> 1 이 나왔다.

이러한 방식을 이용하면 훨씬 계산할 양을 줄어들게 할 수 있다.


2. 룩업테이블

물론 이전 일의 자리수가 같은 지를 통해 룩업 테이블 없이도 도돌이 수를 구할 수 있다.

하지만 최대 4일 뿐더러

1~9까지만 분류하면 되는 것을 우리가 귀찮아 하는 것은 아니기 때문에

룩업테이블을 이용하였다.


3. 사용하는 변수 줄이기

물론 가독성 이라든지 코드 이식성이 떨어질 수 있다.

이 점은 분명 단점이다.

하지만 이 프로그램을 적용해야 되는 곳이 하드웨어 적인 제약이 심한 곳이라 가정하면

사용하는 변수가 적을수록 좋을 것이다.


4. 비트 연산

n2%4해도 되긴 했지만

아무래도 컴퓨터에겐 비트연산이 더 좋을 것이라 여겨 비트 연산을 사용하였다.



ps. 라고 생각했는데 내 알고리즘도 그리 좋진 못한것 같다.