import java.util.*; import java.math.*; /** * Split the champernowne string into different sections to check. The sections are * separated by how many digits are used in consecutive numbers. Brute for the * transitions between the sections by constructing the portion of the champernowne * string where the given string, s, could span sequences of characters with n digits * and sequences with n+1 digits. Then for each run of n digits, try having s start * at each of the n possible offsets. Arrange the characters of s in a grid where each * row is a number in the champernowne string. For all but the last two columns, try * either having the column contain a single value, or two values with a carry somewhere. * If there is a carry we know that the rest of the row must be all 9's. This case will * then fully determine the rest of the grid, and we can just check for consistency. * If there is not a valid carry case, then we can just choose the smallest value for the * column and move onto the next column. Be careful that the first column cannot have a * leading 0. * Brute force the last two columns by just trying each possible pair of digits for * the first row and use that to determine the rest of the grid. * * @author Finn Lidbetter */ public class champernowne_finn { static BigInteger MINUS_ONE = BigInteger.ZERO.subtract(BigInteger.ONE); static long mod = 998_244_353L; static int S_MAX = 25; static char[] champernowne = new char[9 + 2*(99 - 10 + 1) + 3*(133 - 100 + 1)]; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int index = 0; for (int i=1; i<=133; i++) { char[] number = String.format("%d",i).toCharArray(); for (char c: number) { champernowne[index] = c; index++; } } int nTests = Integer.parseInt(sc.nextLine()); for (int testCase=0; testCase= 2*S_MAX) { break; } } curr = curr.add(BigInteger.ONE); } curr = BigInteger.TEN.pow(digits).subtract(BigInteger.ONE); index = S_MAX - 1; while (index>=0) { char[] digitsArr = curr.toString().toCharArray(); for (int i=digitsArr.length-1; i>=0; i--) { brute[index] = digitsArr[i]; vals[index] = curr; offsets[index] = i; index--; if (index<0) { break; } } curr = curr.subtract(BigInteger.ONE); } return new BruteHelper(brute, vals, offsets); } // Get the index of the first digit of `val` in the champernowne string. static BigInteger calculateIndex(BigInteger val, int offset) { int numDigits = val.toString().length(); BigInteger sum = new BigInteger(""+9); for (int digits=2; digits=offset && i=rows) { break; } char ch = puzzle[i][column]; if (ch == '?') { continue; } int val = ch - '0'; int nextVal = (val+1)%10; char nextCh = (char)('0'+nextVal); if (puzzle[i+step][column] != '?' && puzzle[i+step][column] != nextCh) { return false; } puzzle[i+step][column] = nextCh; } for (int i=rows-1; i>=0; i--) { if (i-step<0) { break; } char ch = puzzle[i][column]; if (ch == '?') { continue; } int val = ch - '0'; int nextVal = (val-1+10)%10; char nextCh = (char)('0'+nextVal); if (puzzle[i-step][column] != '?' && puzzle[i-step][column] != nextCh) { return false; } puzzle[i-step][column] = nextCh; } return true; } static boolean isRowFull(char[][] puzzle, int row) { for (int i=0; i=0; i+=direction) { if (direction == 1) { val = val.add(BigInteger.ONE); } else { val = val.subtract(BigInteger.ONE); } char[] digits = val.toString().toCharArray(); if (digits.length!=puzzle[startRow].length) { return false; } for (int j=0;j=puzzle[0].length-2) { // Case 0 int startRow = 0; char[] startRowDigits = new char[puzzle[0].length]; for (int i=0; i=0; startRow--) { for (int j=0; j0 && val1=='0') && !(column==0 && val1=='1')) { startRowDigits[column] = (char)('0'+((val1 + 10 - 1) % 10)); for (int startRow=firstVal1index - 1; startRow>=0; startRow--) { for (int j=0; j qIndices = new ArrayList<>(); for (int i=0; i=lastVal1index; startRow--) { for (int j=0; j=lastVal1index; startRow--) { for (int j=0; j=0; row--) { if (puzzle[row][column]==(char)('0'+val1)) { placeVal1 = true; } if (placeVal1) { puzzle[row][column] = (char)('0' + val1); } } boolean placeVal2 = false; for (int row=0; row