题目链接:https://ac.nowcoder.com/acm/contest/5968
题解链接:
A - 古老的牛市,遗迹的天梯
dp题,没做上来QAQ
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int h[205], dp[205];//dp[i] 跳到第i级阶梯的最小步数
int main(void)
{
int n;
cin >> n;
for (int i = 1; i <= n; i++){
cin >> h[i];
dp[i] = INF;
}
dp[1] = 0;
for (int i = 2; i <= n; i++){
if (h[i] == h[i - 1] + 1)
dp[i] = min(dp[i], dp[i - 1] + 1);
//cout << dp[i] << endl;
for (int j = 1; j < i; j++){ // 枚举所有后退的可能性
int jump = 1 << j; //能跳多少级
int maxh = i - j; //后退之后的级数
while (maxh < n && h[maxh + 1] <= h[i - j] + jump){ // 找到能到的最高阶梯
maxh++;
}
dp[maxh] = min(dp[maxh], dp[i] + j + 1);
}
}
if (dp[n] >= INF)
cout << -1 << endl;
else
cout << dp[n] << endl;
return 0;
}
B - 几乎毁灭牛市的流星雨
实在没想到这里有坑 QAQ
#include <bits/stdc++.h>
using namespace std;
const int N = 305, INF = 0x3f3f3f3f;
typedef pair<int, int> P;
int m;//陨石数目
int dest[N][N];//每个位置毁灭的时间
int t[N][N];//走过的距离,也可以看成时间
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
//记录每个位置毁灭的时间
void op(int x, int y, int t)
{
dest[x][y] = min(dest[x][y], t);
for (int i = 0; i < 4; i++){
int nx = x + dx[i], ny = y + dy[i];
if (nx >= 0 && ny >= 0)
dest[nx][ny] = min(dest[nx][ny], t);
}
}
int bfs()
{
//初始化距离数组
memset(t, INF, sizeof t);
int step = -1;//最终的步数
queue<P> que;
que.push(P(0, 0));
t[0][0] = 0;
while (que.size()){
P p = que.front(); que.pop();
//最后没有被毁灭
if (dest[p.first][p.second] == INF){
step = t[p.first][p.second];
break;
}
//下一秒的走法
for (int i = 0; i < 4; i++){
int nx = p.first + dx[i], ny = p.second + dy[i];
//dest[nx][ny]>t[p.first][p.second]+1 表示到达新位置时,新位置没有被毁灭
if (0 <= nx && nx <= 302 && ny >=0 && ny <= 302 && dest[nx][ny] > t[p.first][p.second] + 1 && t[nx][ny] == INF){
que.push(P(nx, ny));
t[nx][ny] = t[p.first][p.second] + 1;
}
}
}
return step;
}
int main(void)
{
int x, y, t;
memset(dest, INF, sizeof dest);
cin >> m;
for (int i = 0; i < m; i++){
cin >> x >> y >> t;
//记录每个位置毁灭的时间
op(x, y, t);
}
int res = bfs();
cout << res << endl;
return 0;
}