Description
有一头有着N个头的恶龙,有M名骑士,每名骑士有一把魔剑。每一把魔剑有两个参数ci和di。如果当前恶龙的头不小于ci个,则骑士可以使用魔剑砍掉恶龙的恰好ci个头;如果当前恶龙的头小于ci个,则骑士无法使用这把魔剑;如果恶龙还没有死亡(即恶龙的头的个数大于0),则恶龙会立即长出di个头;如果恶龙的头的个数超过L个,则多余的头会脱落,并保持在L个;只有砍掉恶龙所有的头才算是杀死恶龙。
你的任务就是判断这M个骑士能否杀死恶龙,如果可以,请输出最少需要使用魔剑的次数,否则输出“-1”。
Input
输入数据的第一行是三个整数N,M,L(1≤N≤500,1≤M≤10,N≤L≤N+500),表示恶龙有N个头,骑士数目为M,恶龙的头的数量限制为L。紧接着M行,第i行有两个整数ci,di(0≤ci,di≤1,000,1≤i≤M),表示第i把魔剑的参数。如果能够杀死恶龙,则输出最少需要使用魔剑的次数,否则输出“-1”。每把魔剑的使用次数是无限的。
Output
输出一行一个整数B,表示能够杀死恶龙时最少需要使用魔剑的次数,如果不能杀死恶龙,输出-1
Sample Input
20 2 500
7 1
8 5
Sample Output
3
思路是:
bfs暴力+剪枝判断能否杀死。(如果没砍死加上d[i],已经出现过,就不用加入到队列里了)
具体用代码解释比较清晰。
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
int n, m, L;
int c[1005], d[1005], vis[1005];
struct node{
int num, t;
node(int _num = 0, int _t = 0) : num(_num), t(_t) {}
};
int bfs(){
queue<node> q;
memset(vis, 0, sizeof(vis));
node now, next;
q.push(node(n, 0));
vis[n] = 1;
while(!q.empty()) {
now = q.front();
q.pop();
for(int i = 1; i <= m; i++) {
if(now.num == c[i]) return now.t + 1;
if(now.num > c[i]) {
next.num = min(now.num - c[i] + d[i], L);
next.t = now.t + 1;
if(vis[next.num] == 0) {
vis[next.num] = 1;
q.push(next);
}
}
}
}
return -1;
}
int main(void) {
while(cin >> n >> m >> L) {
for(int i = 1; i <= m; i++) {
cin >> c[i] >> d[i];
}
cout << bfs() << endl;
}
return 0;
}