Problem Description
There is an integer a
and n
integers b1,…,bn.
After selecting some numbers from b1,…,bn
in any order, say c1,…,cr,
we want to make sure that a mod c1 mod c2 mod… mod cr=0
(i.e., a
will become the remainder divided by ci
each time, and at the end, we want a
to become 0).
Please determine the minimum value of r.
If the goal cannot be achieved, print −1
instead.
Input
The first line contains one integer
T≤5,
which represents the number of testcases.
For each testcase, there are two lines:
1. The first line contains two integers n and a (1≤n≤20,1≤a≤106).
2. The second line contains n integers b1,…,bn (∀1≤i≤n,1≤bi≤106).
For each testcase, there are two lines:
1. The first line contains two integers n and a (1≤n≤20,1≤a≤106).
2. The second line contains n integers b1,…,bn (∀1≤i≤n,1≤bi≤106).
Output
Print T
answers in T
lines.
Sample Input
2 2 9 2 7 2 9 6 7
Sample Output
2 -1
题解:暴力做法,不过用的是递归,每次选一个数我可以选择除当前数或者不除当前数,就这两个选择。时间复杂度2的n次方,n<=20,可以过。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[30];
int res;
int min(int a,int b)
{
return a > b ? b : a;
}
bool com(int a,int b)
{
return a > b;
}
void dfs(int n,int r,int c,int d)
{
if(c >= n)
{
return;
}
if(0 == r % a[c]) //找到一组
{
res = min(d + 1,res);
}
dfs(n,r % a[c],c + 1,d + 1); //除当前数
dfs(n,r,c + 1,d); //不除当前数
}
int main()
{
int T;
cin>>T;
int n,m;
while(T--)
{
res = 100;
scanf("%d%d",&n,&m);
for(int i = 0;i < n;i++)
{
scanf("%d",a + i);
}
sort(a,a + n,com); //必须从最大的开始,从小的开始的话,一旦取余就永远得到余数了,因为余数肯定小于后面的数
dfs(n,m,0,0);
if(100 == res)
{
printf("-1\n");
}
else
{
printf("%d\n",res);
}
}
return 0;
}