Question:
Give you a N and K, ask to find M, meet the following conditions
1. The length of m is the same as that of N.
2. M % K = 0
3. If conditions 1 and 2 are met, the number of different digits of M and N must be as few as possible.
4. satisfy the conditions 1, 2, 3, and m must be the minimum
Difficulties:
1. n is the number of digits up to 100 bits. How to deal with high precision? How to solve M % K = 0
Method: Same-remainder modulo
A + B = A % m + B % m
A * B = (a % m) * (B % m)
Definition:
Int mod [110] [110];
MoD [I] [J] = [(10 ^ I) * j] % K
MoD [I] [J] = (mod [I-1] [J] * 10) % K
2. How to meet conditions
Pay attention to the order of search. The number of times from 0 to the len-1 began to search, first search for a small number, then search for a large number
3. DFS
The passed parameters include DFS (Num, start, end, m)
Num indicates the number of times to change the number. [start, end] indicates the number of search intervals, and M indicates the remainder of the modulo K.
4. Search for TLE directly ..
Memory-based search is required ..
DP [num] [m] = C indicates that the number of searches is num, the remainder is m, and no solution is obtained in the range (0, C-1.
View code
# Include <stdio. h> # include <string. h> # include <stdlib. h ># include <iostream> using namespace STD; char STR [1000]; int mod [110] [110]; // mod [I] [J] = (10 ^ I) * j) % K, same modulus formula; int N, K, Len; int DP [110] [11110];/* the condition that is met determines the search order: 1. same length as N digits 2. can be divisible by K3. the number of digits should be the same as N 4. the index is in the interval [0, it is not true when the command is run on the computer or on the computer. */Void Init () {for (INT I = 0; I <= 9; I ++) {mod [0] [I] = I % K ;} for (INT I = 1; I <= Len; I ++) {for (Int J = 0; j <= 9; j ++) moD [I] [J] = (mod [I-1] [J] * 10) % K;} bool DFS (INT S, int POs, int length, int m) {If (M = 0) {for (INT I = 0; I <Len; I ++) printf ("% C", STR [I]); puts (""); Return true;} If (S = 0 | DP [s] [m]) return false; // first search for numbers smaller than N for (INT x = Pos; x <= length; X ++) {( Int I = 0; I <STR [x]-'0'; I ++) // search from 0 to STR [X, ensure that the minimum {If (x = 0 & I = 0) // The first number cannot be 0 continue; int temp = m-mod [Len-1-x] [STR [x]-'0'] + mod [len-1-x] [I]; If (temp <0) temp + = K; TEMP % = K; char c = STR [X]; STR [x] = I + 48; If (DFS (s-1, POS + 1, length, temp) return true; STR [x] = C ;}// search for a number larger than N for (INT x = length; x> = Pos; X --) {for (INT I = STR [x]-'0' + 1; I <= 9; I ++) {I F (x = 0 & I = 0) continue; int temp = m-mod [Len-1-x] [STR [x]-'0'] + mod [len-1-x] [I]; If (temp <0) temp + = K; TEMP % = K; char c = STR [X]; STR [x] = I + 48; If (DFS (s-1, POs, length-1, temp) return true; STR [x] = C ;}// If no result is found, Mark DP [s] [m] = Length + 1; // when the number of times is J and the remainder is m, return false is not returned in the range (0, length);} int main () {While (scanf ("% S % d", STR, & K )! = EOF) {Len = strlen (STR); Init (); int sum = 0; Int J = 0; For (INT I = len-1; I> = 0; I --) {int x = STR [I]-'0'; sum + = mod [J] [X]; sum % = K; j ++;} memset (DP, 0, sizeof (DP); For (INT I = 0; I <Len; I ++) {If (DFS (I, 0, len-1, sum )) break;} return 0 ;}