(CF 788)C. The Great Mixing <BFS>

来源:互联网 发布:sql 试图 编辑:程序博客网 时间:2024/05/20 14:28

题目链接: http://codeforces.com/problemset/problem/788/C

C. The Great Mixing

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Sasha and Kolya decided to get drunk with Coke, again. This time they have k types of Coke. i-th type is characterised by its carbon dioxide concentration . Today, on the party in honour of Sergiy of Vancouver they decided to prepare a glass of Coke with carbon dioxide concentration . The drink should also be tasty, so the glass can contain only integer number of liters of each Coke type (some types can be not presented in the glass). Also, they want to minimize the total volume of Coke in the glass.

Carbon dioxide concentration is defined as the volume of carbone dioxide in the Coke divided by the total volume of Coke. When you mix two Cokes, the volume of carbon dioxide sums up, and the total volume of Coke sums up as well.

Help them, find the minimal natural number of liters needed to create a glass with carbon dioxide concentration . Assume that the friends have unlimited amount of each Coke type.

Input
The first line contains two integers n, k (0 ≤ n ≤ 1000, 1 ≤ k ≤ 106) — carbon dioxide concentration the friends want and the number of Coke types.

The second line contains k integers a1, a2, …, ak (0 ≤ ai ≤ 1000) — carbon dioxide concentration of each type of Coke. Some Coke types can have same concentration.

Output
Print the minimal natural number of liter needed to prepare a glass with carbon dioxide concentration , or -1 if it is impossible.

Examples
input
400 4
100 300 450 500
output
2
input
50 2
100 25
output
3
Note
In the first sample case, we can achieve concentration using one liter of Coke of types and : .

In the second case, we can achieve concentration using two liters of type and one liter of type: .

题意:
有k个正整数,和一个正整数n,问你这k个数中最少取几个数可以使得他么你的平均数为n?(每个数可以重复取)

分析:
假设有m个数的平均数为n.那么 (a1 + a2 + a3 + …+ am) / m = n
问最少几个数所以我们可以使用bfs按照取数的个数一个个搜索,然后记录他们的和值和数的数目即可。但是这样的数据范围很大,使得时间复杂度无法承受。
我们将式子变形:
(a1 + a2 + a3 + …+ am) = n * m
a1 - n + a2 - n + a3 - n + … + am - n = 0
所以将每个数减去n后就变成了,问你最少取多少个数可以使得他们的和为0
并且我们知道 -1000 <= ai - n <= 1000 所以在搜索的过程中我们只需要考虑2000种情况即可。 (要是某种情况的和值不在这个范围内部,那说明你一定在某个在这个范围内的数上多加了(减了)一个没必要的值)

所以接下来我们直接用BFS搜索即可了。注意在此之前要去掉重复的值
并且因为数据存在负数值所以我们在记录时将整体的数据向右平移了rmove = 1000

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <cmath>using namespace std;const int maxn = 2010;int a[1000010];int qu[maxn];    int ans[maxn];  //记录和值所需要的数的个数bool vis[maxn];  int main(){    int n,k;    int rmove  = 1000;    scanf("%d%d",&n,&k);    memset(vis,0,sizeof(vis));    memset(ans,0,sizeof(ans));    for(int i=0;i<k;i++) scanf("%d",&a[i]);    sort(a,a+k);    k = unique(a,a+k) - a;    for(int i=0;i<k;i++) a[i] -= n;    if(a[0] * a[k-1] > 0)    {        printf("-1\n");        return 0;    }    int s = 1, t = 1;    for(int i=0;i<k;i++)    {        qu[t++] = a[i];        ans[a[i] + rmove] = 1;        vis[a[i] + rmove] = 1;    }    while(s != t && !vis[rmove])    {        for(int i=0;i<k;i++)        {            if(abs(qu[s] + a[i]) <= rmove && !vis[qu[s] + a[i] + rmove])            {                qu[t++] = qu[s] + a[i];                vis[qu[s] + a[i] + rmove] = 1;                ans[qu[s] + a[i] + rmove] = ans[qu[s] + rmove] + 1;            }        }        s++;    }    printf("%d\n",ans[rmove]);    return 0;}
0 0
原创粉丝点击