HDU 2181 哈密顿绕行世界问题
不解释
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rep( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define clr( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define bug(x) cout<<#x<<":"<<(x)<<endl;
vector<int> v[21];
int s;
int ans[21],vis[21];
int tol;
void dfs(int u,int cnt){
if(cnt == 20){
rep(i,0,2){
if(v[u][i] == s){
cout<<tol++<<": ";
rep(i,1,20){
cout<<ans[i]<<" ";
}
cout<<s<<endl;
}
}
}
rep(i,0,2){
int tv = v[u][i];
if(!vis[tv]){
vis[tv] = 1;
ans[cnt+1] = tv;
dfs(tv,cnt+1);
vis[tv] = 0;
}
}
}
int main(){
// RE
int a;
rep(i,1,20){
rep(j,1,3){
cin>>a;
v[i].push_back(a);
}
}
while(cin>>s,s){
clr(vis,0);
tol = 1;
vis[s] = 1;
ans[1] = s;
dfs(s,1);
}
return 0;
}
HDU 3533 Escape
此题巨坑,题意也很难看懂。
1.从(0,0)点走到(n,m),四个方向(或者不走),每次走或不走都消耗1能量,求最少消耗。
2.有很多炮台,在各自的x,y处向某个方向间隔t秒发一次速度为v的炮,炮打到其他炮台就消失(炮消失但炮塔不消失),炮炮之间可以穿越,人不能碰到炮台。
3.炮台的攻击只在炮终点的同一时刻起效,即可以想象为炮是从抛物线那样飞下来的,只有在同一点同一时刻才起效果。
坑点在哪呢?在坐标系。按照它的图片坐标系而言,输入的炮台X,Y是要反过来的(难怪看别人博客都是n和m跟题目的反过来)我只反了输入的炮台XY就行了。数组要开bool,开int会MLE。
解:正常BFS,难点在判断某点某时刻是否会被炮打中。看起来是动态图,但可以通过预处理变成静态,即我们是知道哪些点在哪些时刻是危险的。
两个for循环,外层为同条线的坐标(范围是碰到其他炮台或者坐标上下限),内层为时间,比如:
if(pao[i].dir == 'E'){
int stop = n;
for(int j = x + 1; j <= n; j++){
if(cast[j][y]){
stop = j;
break;
}
}
int curTime = 1;
for(int j = x+v;j<=stop;j+=v,curTime++){
for(int k=curTime;k<=d;k+=t){
fire[j][y][k] = true;
}
}
}
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rep( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define clr( a , x ) memset ( a , x , sizeof (a) );
#define RE freopen("1.in","r",stdin);
#define WE freopen("1.out","w",stdout);
#define MOD 10009
#define bug(x) cout<<#x<<":"<<(x)<<endl;
const int maxn = 102;
struct Pao{
char dir;
int x,y,t,v;
}pao[maxn];
struct node{
int x,y,step;
};
int dir[5][2]={{-1,0},{1,0},{0,1},{0,-1},{0,0}};
bool vis[maxn][maxn][1002];
int n,m,k,d;
bool place(int x,int y){
if(x >= 0 && x <= n)
if(y >= 0 && y <= m)
return true;
return false;
}
bool fire[maxn][maxn][1002]; //该点该时刻是否危险
bool cast[maxn][maxn];
void init(){
int x,y,v,t;
clr(fire,false);
rep(i,0,k-1){
x = pao[i].x,y = pao[i].y,v = pao[i].v,t = pao[i].t;
if(pao[i].dir == 'E'){
int stop = n;
for(int j = x + 1; j <= n; j++){
if(cast[j][y]){
stop = j;
break;
}
}
int curTime = 1;
for(int j = x+v;j<=stop;j+=v,curTime++){
for(int k=curTime;k<=d;k+=t){
fire[j][y][k] = true;
}
}
}else if(pao[i].dir == 'W'){
int stop = 0;
for(int j = x - 1; j >= 0; j--){
if(cast[j][y]){
stop = j;
break;
}
}
int curTime = 1;
for(int j = x-v;j>=stop;j-=v,curTime++){
for(int k=curTime;k<=d;k+=t){
fire[j][y][k] = true;
}
}
}else if(pao[i].dir == 'N'){
int stop = 0;
for(int j = y - 1; j >= 0; j--){
if(cast[x][j]){
stop = j;
break;
}
}
int curTime = 1;
for(int j = y-v;j>=stop;j-=v,curTime++){
for(int k=curTime;k<=d;k+=t){
fire[x][j][k] = true;
}
}
}else if(pao[i].dir == 'S'){
int stop = m;
for(int j = y + 1; j <= m; j++){
if(cast[x][j]){
stop = j;
break;
}
}
int curTime = 1;
for(int j = y+v;j<=stop;j+=v,curTime++){
for(int k=curTime;k<=d;k+=t){
fire[x][j][k] = true;
}
}
}
}
}
int bfs(){
node s,e,now,t;
s.x = s.y = 0, s.step = 0;
e.x = n,e.y = m;
clr(vis,0);
vis[0][0][0] = true;
queue<node>q;
q.push(s);
while(!q.empty()){
now = q.front();q.pop();
rep(i,0,4){
t.x = now.x + dir[i][0];
t.y = now.y + dir[i][1];
t.step = now.step + 1;
if(t.step > d)
break;
if(!place(t.x,t.y)) //在坐标范围内
continue;
if(vis[t.x][t.y][t.step])
continue;
if(cast[t.x][t.y]) //碰到炮台
continue;
if(fire[t.x][t.y][t.step]) //这一点这一时刻有危险
continue;
if(n - t.x + m - t.y > (d-t.step)) //曼哈顿距离剪枝(测试发现这题里没有效果)
continue;
if(t.x == e.x && t.y == e.y)
return t.step;
vis[t.x][t.y][t.step] = true;
q.push(t);
}
}
return -1;
}
int main(){
// RE
while(cin>>m>>n>>k>>d){
clr(cast,false);
rep(i,0,k-1){
cin>>pao[i].dir>>pao[i].t>>pao[i].v>>pao[i].y>>pao[i].x;
cast[pao[i].x][pao[i].y] = true;
}
if(cast[n][m]){
puts("Bad luck!");
continue;
}
init();
int ans = bfs();
if(ans == -1)
cout<<"Bad luck!"<<endl;
else
cout<<ans<<endl;
}
return 0;
}