Zoj2599: Graduated lexicographical ordering (very classic digital DP)

Source: Internet
Author: User

Consider integer numbers from 1 to n. Let us call the sum of digits of an integer number its weight. denote the weight of the number X as W (X ).

Now let us order the numbers using so calledGraduated lexicographical Ordering, Or shorter grlex ordering. consider two integer numbers A and B. if W (a) <W (B) then a goes before B in grlex ordering. if W (A) = W (B) then a goes before B in grlex ordering if and only if the decimal representation of a is lexicographically smaller than the decimal representation of B.

Let us consider some examples.

  • 120 <grlex4 since w (120) = 1 + 2 + 0 = 3 <4 = W (4 ).
  • 555 <grlex78 since w (555) = 15 = W (78) and "555" is lexicographicaly smaller than "78 ".
  • 20 <grlex200 since w (20) = 2 = W (200) and "20" is lexicographicaly smaller than "200 ".

Given N and Some integer number k, find the position of the number k in grlex ordering of integer numbers from 1 to n, and the k-th number in this ordering.


Input

There are several lines in the input file, and each line stands two integers N and K (1 <= k <= n <= 1018 ). A line with N = k = 0 ends up the input.


Output

For each line in the input, output one line in the output file. first print the position of the number k in grlex ordering of integer numbers from 1 to n, and then the integer that occupies the k-th position in this ordering.


Sample Input

20 100 0

Sample output

2 14
 

Question: First Set 1 ~ The number in N is in the order of digits and digits, and then the number is equal to the number in the Lexicographic Order. Then, the K position and the K position are output.

In Gao yihan's paper research on the solution to digital counting problems
He provides five functions.

1. getsum1 (int l, int sum)

2. getsum2 (ll n, int sum); 1 ~ is returned ~ The sum of numbers in N

3. getsum3 (ll n, ll prefix, int sum); 1 ~ is returned ~ The number of numbers in n that are prefixed with Sum

4. getsum4 (ll n, ll K, int sum); 1 ~ is returned ~ The number in N is sum and the Lexicographic Order is less than K.

5. getsum5 (ll n, ll K); Return K in 1 ~ Position in N

Use these five functions to solve this problem.
After submitting zoj, I was surprised to find that I had ranked D 2nd, and the running time was the same as that of 1st and memory, but he submitted it in and I submitted it in 14 years.
 
 
# Include <stdio. h> # include <string. h >#include <algorithm> using namespace STD; # define ll _ int64 # define up (I, x, y) for (I = x; I <= y; I ++) # define down (I, x, y) for (I = x; I> = y; I --) # define MEM (a, B) memset (, b, sizeof (A) # define W (x) while (x) ll N, K; ll DP [20] [1, 200]; // The number of numbers and the number of the L-digit sum (also counted with the 0 prefix) ll getsum1 (int l, int sum) {If (sum> 9 * l | sum <0 | L <0) return 0; If (DP [l] [Sum]) return DP [l] [Sum]; If (! L &&! Sum) return 1; int I; up (I,) {If (Sum-I <0) break; DP [l] [Sum] + = getsum1 (L-1, sum-I);} return DP [l] [Sum];} // return 1 ~ The sum of numbers in N ll getsum2 (ll n, int sum) {int bit [20], I, Len = 0, J; ll ans = 0; W (n) {bit [Len ++] = n % 10; N/= 10;} Down (I, len-1, 0) {up (J, 0, bit [I]-1) ans + = getsum1 (I, sum --);} ans + = getsum1 (0, sum); Return ans;} // return 1 ~ Number of numbers in n that are prefixed with Sum ll getsum3 (ll n, ll prefix, int sum) {char Sn [20], SP [20]; int ln, LP, I, j; ll ans = 0; sprintf (Sn, "% i64d", n); // converts a number to a string sprintf (SP, "% i64d ", prefix); Ln = strlen (SN), Lp = strlen (SP); up (I, 0, Lp-1) sum-= Sp [I]-'0 '; up (I, 0, Lp-1) if (Sn [I]! = Sp [I]) break; if (I <LP) {If (Sn [I] <SP [I]) ln --; // if this digit of the prefix is greater than N, it will be matched from the second High Position and treated as the length of N minus 1 down (I, Ln-LP, 0) ans + = getsum1 (I, sum); return ans;} ll TEM = 0; up (I, LP, ln-1) TEM = TEM * 10 + Sn [I]-'0 '; ans + = getsum2 (TEM, sum); down (I, ln-lp-1, 0) ans + = getsum1 (I, sum); Return ans;} // return 1 ~ The number in N is sum and the Lexicographic Order is less than K. ll getsum4 (ll n, ll K, int sum) {int bit [20], I, Len = 0, J, T = 1; ll ans = 0, pre = 1; W (k) {bit [Len ++] = K % 10; k/= 10;} Down (I, len-1, 0) // enumerative prefix {up (J, T, bit [I]-1) {ans + = getsum3 (n, pre ++, sum );} pre * = 10; t = 0;} // For example 1000, less than K has 100, these are not involved in the previous statistical process up (I, 0, len-1) {If (bit [I] = 0) ans ++; else break;} return ans;} // The returned K value ranges from 1 ~ Position in N ll getsum5 (ll n, ll K) {ll sum = 0, TEM = K, ANS = 0, I; while (TEM) {sum + = (TEM % 10); TEM/= 10;} Up (I, 1, Sum-1) // calculate the sum of the sum and sum. ans + = getsum2 (n, I); ans + = getsum4 (n, k, sum); // sum equals to sum, however, the number of lexicographic orders less than K returns ans + 1; // located in the last position of those numbers} int main () {MEM (DP, 0 ); W (scanf ("% i64d % i64d", & N, & K), N + k) {printf ("% i64d", getsum5 (n, k )); ll pre = 1, presum = 1, sum = 1, t; W (t = getsum2 (n, sum) <k) // counts the number and, starting from 1, determine the number at the K position and {sum ++; k-= T;} W (1) {W (t = getsum3 (n, pre, sum) <k) // determine the number of digits at the K position, and then compare the prefix to find the number at the K position {pre ++; presum ++; k-= T;} If (presum = sum) break; // digit and OK Pre * = 10;} W (-- k) Pre * = 10; // because the numbers are determined and the prefixes are the same, they may be 100 or. You must also consider printf ("% i64d \ n", pre );} return 0 ;}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.