简单搜素题集



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;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值