You recently acquired a new microwave, and noticed that it provides a large number of buttons to be able to quickly specify the time that the microwave should be running for. There are buttons both for adding time, and for subtracting time. You wonder how efficient you can be when entering cooking times: you want to minimize the number of required button presses.
The microwave can be running for at least 0 seconds, and at most 1 hour. If a button press would result in a cooking time of less than 0 seconds, the microwave will set the cooking time to 0 seconds. If a button press would result in a cooking time of more than 1 hour, the microwave will set the cooking time to 1 hour. Initially, the microwave will run for 0 seconds. There will always be a button adding at least 1 second to the cooking time.
Given the buttons that the microwave provides for entering cooking times, determine the least amount of button presses required to let the microwave run for a certain amount of time. If it is not possible to enter the desired cooking time precisely, determine the smallest achievable cooking time above the target, and the minimum number of button presses required for that cooking time, instead. The microwave does not allow to adjust the cooking time once it has started cooking.
Input
On the first line one positive number: the number of test cases, at most 100. After that per test case:
-
one line with two space-separated integers n and t (1 ≤ n ≤ 16 and 0 ≤ t ≤ 3600): the number of buttons available to change the cooking time, and the desired cooking time in seconds, respectively.
-
one line with n space-separated integers bi (-3600 ≤ bi ≤ 3600): the number of seconds added to the cooking time when button i is pressed.
Output
Per test case:
one line with two space-separated integers: the minimum number of button presses required to reach the required cooking time, and the minimum number of extra seconds that the microwave must be running for, respectively.
Sample Input
2
3 50
-10 10 60
1 50
20
Sample Output
2 0
3 10
题意:
给出n,m,代表微波炉有n个按钮,要求达到总时间为m
然后给出n个数,代表n个按钮能增加的时间,问最少几步,能够使得按出的总时间大于等于要求的时间,并且相差最小
输出最小的步数与相差的最小值
要求,当总时间小于0时,时间为0,大于3600时,时间为3600
思路:
先找出按一次能得到的值并记录按的按钮数,紧接着按第二次能得到的值,
并判断此时的值在之前有没有出现过,若有,不入队,因为之前出现的肯定按钮数更少
入队更新了。若之前没有出现过,那就入队,并在之前到达当前值的步数加1。
直接暴力BFS,用VIS记录步数
#include<cstdio>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<iostream>
#include<map>
#include<queue>
#define mes(a,b) memset(a,b,sizeof(a))
#define rep(i,m,n) for(i=m;i<=n;i++)
typedef long long ll;
using namespace std;
int max3(int a,int b,int c){return max(max(a,b),c);}
ll min3(ll a,ll b,ll c){return min(min(a,b),c);}
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int mod=1e9+7;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
ll Fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n;n=n*n;}return r;}
int t,n,m;
int a[20];
int vis[100010];
void bfs()
{
mes(vis,inf);
queue<int> Q;
Q.push(0);
vis[0] = 0;
while(!Q.empty())
{
int x = Q.front();
Q.pop();
for(int i = 0; i<n; i++)
{
int next = x+a[i];
if(next<0)
next = 0;
if(next>3600)
next = 3600;
if(vis[next]<=vis[x]+1)
continue;
vis[next] = vis[x]+1;
Q.push(next);
}
}
}
int main()
{
int i,j,k;
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&n,&t);
for(i = 0; i<n; i++)
scanf("%d",&a[i]);
bfs();
for(i = t; i<=3600; i++)
{
if(vis[i]!=inf)
{
break;
}
}
printf("%d %d\n",vis[i],i-t);
}
return 0;
}