import java.util.*;
import java.io.*;
class Solution
{
public static void main(String args[]) throws Exception
{
// System.setIn(new FileInputStream("res/input.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T;
T=Integer.parseInt(br.readLine().trim());
for(int test_case = 1; test_case <= T; test_case++)
{
StringTokenizer st = new StringTokenizer(br.readLine().trim());
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
TreeSet<String> nums = new TreeSet<>(Collections.reverseOrder());
StringBuilder sb = new StringBuilder(br.readLine().trim());
// System.out.printf("case %d\n", test_case);
for (int iter = 0; iter < N; ++iter) {
sb.append(sb.charAt(0));
sb.deleteCharAt(0);
for (int numIdx = 0; numIdx < 4; numIdx++) {
String num = sb.substring(numIdx * (N/4), numIdx * (N/4) + (N/4));
// System.out.println(num);
if (!nums.contains(num)) {
nums.add(num);
}
}
}
while (K > 1) {
nums.pollFirst();
--K;
}
String max = nums.pollFirst();
int numericNum = 0;
int base = 1;
for (int idx = max.length() - 1; idx >= 0; --idx) {
char ch = max.charAt(idx);
if (ch >= 'A' && ch <= 'F') {
numericNum += base * (ch - 'A' + 10);
} else {
numericNum += base * (ch - '0');
}
base *= 16;
}
bw.write("#" + test_case + " " + numericNum + '\n');
}
bw.flush();
bw.close();
}
}
문제 설명이 좀 요상하다. 설명하자면 각 변의 숫자가 수고, 숫자 최대 길이는 N에 따라 유동적이다. 따라서 최대로 가능한 숫자가 16진수로 7자리, 그러니까 28bit인 경우여서 int로도 전부 해결이 가능하긴 하다.
ASCII 특성을 활용했다. A
가 0
보다 크기 때문에, 그냥 String
째로 순서를 비교해도 문제가 없다. 중복을 제거해야 함 + K번째 큰수를 구해야 하기 때문에 TreeSet
을 활용했다. 중복 파악이 쉽고, 순서대로 정렬이 가능하기 때문. 이 때 최대값이 top에 가야하기 때문에 Collections.reverseOrder()
을 해야한다는 것도 유의.
모든 회전에 대해 시도를 하며, String
조작은 StringBuilder
을 활용했다. 변환은 밑을 활용해서 직관적으로 하면 된다.