Codeforces Round #698 (Div. 2) - B. Nezzar and Lucky Number 题解

Codeforces Round #698 (Div. 2)-B. Nezzar and Lucky Number

传送门
Time Limit: 1 second
Memory Limit: 512 megabytes

Problem Description

Nezzar’s favorite digit among 1 , … , 9 1,\ldots,9 1,,9 is d d d. He calls a positive integer lucky if d d d occurs at least once in its decimal representation.

Given q q q integers a 1 , a 2 , … , a q a_1,a_2,\ldots,a_q a1,a2,,aq, for each 1 ≤ i ≤ q 1 \le i \le q 1iq Nezzar would like to know if a i a_i ai can be equal to a sum of several (one or more) lucky numbers.

Input

The first line contains a single integer t t t ( 1 ≤ t ≤ 9 1 \le t \le 9 1t9) — the number of test cases.

The first line of each test case contains two integers q q q and d d d ( 1 ≤ q ≤ 1 0 4 1 \le q \le 10^4 1q104, 1 ≤ d ≤ 9 1 \le d \le 9 1d9).

The second line of each test case contains q q q integers a 1 , a 2 , … , a q a_1,a_2,\ldots,a_q a1,a2,,aq ( 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1ai109).

Output

For each integer in each test case, print “YES” in a single line if a i a_i ai can be equal to a sum of lucky numbers. Otherwise, print “NO”.

You can print letters in any case (upper or lower).

Sample Input

2
3 7
24 25 27
10 7
51 52 53 54 55 56 57 58 59 60

Sample Onput

YES
NO
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
NO

Note

In the first test case, 24 = 17 + 7 24 = 17 + 7 24=17+7, 27 27 27 itself is a lucky number, 25 25 25 cannot be equal to a sum of lucky numbers.

题目大意

Nezzar的幸运数字是d,一个十进制数中任何一位出现了d就是lucky number。问一个数n能不能拆成lucky number的和。

例:假如Nezzar的幸运数字d=3,那么3,13,32等都是lucky number。


解题思路

首先不难发现,当n≥10*d时,一定是lucky number。

因为一个n可以拆成10*d+(k) + d+d+…+d (k<10)。
看不懂没关系,举个例子:

假如Nezzar的幸运数字是7,那么70≤n≤79时,n直接就是lucky number(十位数含7);
当n>=80时,n可以拆成七十几加j个7。
如:83 = 76 + 7;138 = 75 + 7 + 7 + … +7。

关键就在于n<10*d时,能不能拆成lucky number的和。

接下来只考虑n<10*d的情况。
对于一个特点的d,首先d的倍数是一定可以拆成几个d的和的。
can[d][n]来记录幸运数字是d时n能不能拆成lucky number。

初始值bool can[10][91]={false};,之后对于每一个d∈[1,9],d的倍数全为true。

for (int d = 1; d <= 9; d++)
{
    for (int k = 1; k <= 10; k++)
    {
        can[d][d * k] = true;
    }
}

然后,我们可以发现,对于d=3, 13和23也是lucky number。
那么13加上3的倍数也是lucky number。
23加上其他lucky number也是lucky number。

同理,对于d=8, 18、28、38…88都是lucky number。
它们加上其他lucky number也都是lucky number。

for (int d = 1; d <= 9; d++)
{
    for (int k = 1; k <= d; k++)  //例如d=3,那么就需要把13、23变成true
	{
		int thisOne = k * 10 + d; //13、23
		can[d][thisOne] = true; 
		for (int j = 1; j + thisOne <= d * 10; j++) //这个数加上所有的lucky number都是lucky number,枚举所有考虑范围内的数
		{
			if (can[d][j])
			{
				can[d][j + thisOne] = 1;
			}
		}
	}
}

至此,我们已经获得了所有≤10*d的lucky number了。

万事俱备,只欠东风。
给一个数n,如果n<10*d,就看看can[d][n]是否为true就行了。

AC代码

#include <bits/stdc++.h>
using namespace std;
bool can[10][91] = {
    
    0};
void init()
{
    
    
	for (int d = 1; d <= 9; d++)
	{
    
    
		for (int k = 1; k <= 10; k++)
		{
    
    
			can[d][d * k] = true;
		}
	}
	for (int d = 1; d <= 9; d++)
	{
    
    
		for (int k = 1; k <= d; k++) //例如d=3,那么就需要把13、23变成true
		{
    
    
			int thisOne = k * 10 + d; //13、23
			can[d][thisOne] = true;
			for (int j = 1; j + thisOne <= d * 10; j++) //这个数加上所有的lucky number都是lucky number,枚举所有考虑范围内的数
			{
    
    
				if (can[d][j])
				{
    
    
					can[d][j + thisOne] = 1;
				}
			}
		}
	}
}
int main()
{
    
    
	init();
	int N;
	cin >> N;
	while (N--)
	{
    
    
		int n, d;
		cin >> n >> d;
		for (int i = 0; i < n; i++)
		{
    
    
			int t;
			scanf("%d", &t);
			if (t >= d * 10)
				puts("YES");
			else
				puts(can[d][t] ? "YES" : "NO");
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Tisfy/article/details/113387912