HIHO #1308 : 搜索二·骑士问题

原创 2016年08月29日 09:03:55

题目链接

可以直接跑三次bfs,也可以使用18位的二进制表示3个人的状态,一次bfs,因为坐标在0-7,所以一个数字只用3位就够了,然后6个数字,一共18位就够了

#include<bits/stdc++.h>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define fastIO ios::sync_with_stdio(false);cin.tie(0);
#define LL long long
#define pb push_back
#define gcd __gcd


#define For(i,j,k) for(int i=(j);i<=k;i++)
#define lowbit(i) (i&(-i))
#define _(x) printf("%d\n",x)

typedef vector<LL> vec;
const double EPS = 1e-8;
const int maxn = 5e6+10;
const int inf  = 1 << 28;

bool vis[1<<20];
int step[1<<20];
int len  = (1 <<  6) - 1;
int len2 = (1 << 12) - 1;
int len3 = (1 << 18) - 1;

int dir[][8]= {{1,-1,2,-2,-2,-1,1,2},{2,2,1,1,-1,-2,-2,-1}};
bool check(int x) {
    if( (x & len) == ((x >> 6) & len) && (x & len) == ((x >> 12) & len) ) return true;
    return false;
}

int getPos(int num,int dx,int dy) { // num <==> ... ... 6位,前3位x,后三位y
    int y = num & 7;// 111 & num
    int x = num >> 3 & 7;

    int xx = x + dx;
    int yy = y + dy;

    if(xx < 0 || yy < 0 || xx >= 8 || yy >= 8)return -1;

    return xx << 3 | yy;
}


int bfs(int s) {
    queue<int> q;
    cl(vis,false);
    cl(step,0);

    vis[s] = true;
    step[s] = 0;
    q.push(s);

    while(!q.empty()) {
        int x = q.front();q.pop();
        if(check(x)) {
            return step[x];
        }

        int aim;
        for(int i=0; i<=12; i+=6) {
            int cur = x >> i & len;// three people

            for(int j=0; j<8; j++) {

                int tmp = getPos(cur,dir[0][j],dir[1][j]);

                if(tmp == -1)continue;

                if(i ==  0) aim = x & (len3 ^ len);
                if(i ==  6) aim = x & (len3 ^ len2) | (x & len);
                if(i == 12) aim = x & len2;

                aim |= (tmp << i);
                if(!vis[aim]) {
                    vis[aim] = true;
                    q.push(aim);
                    step[aim] = step[x] + 1;
                }
            }
        }
    }
}

char str[4];
int main() {

    int T;
    scanf("%d",&T);
    while(T--) {
        int k = 12;
        int state = 0;
        for(int i=0; i<3; i++) {
            scanf("%s",str);
            int x = str[0] - 'A';
            int y = str[1] - '1';
            state |=(x << 3 | y) << k;
            k-=6;
        }

        printf("%d\n",bfs(state));
    }
    return 0;
}

跑三次bfs的

#include<bits/stdc++.h>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define fastIO ios::sync_with_stdio(false);cin.tie(0);
#define LL long long
#define pb push_back
#define gcd __gcd

#define For(i,j,k) for(int i=(j);i<k;i++)
#define lowbit(i) (i&(-i))
#define _(x) printf("%d\n",x)

const double EPS = 1e-8;
const int maxn = 1e6+10;
const int inf  = 1 << 28;

int dis[3][10][10];
bool vis[10][10];
int dir[][8]= {{1,-1,2,-2,-2,-1,1,2},{2,2,1,1,-1,-2,-2,-1}};
void bfs(int t,int x,int y){
    queue<pair<int,int> > q;
    cl(vis,false);
    cl(dis[t],0x3f);

    q.push(make_pair(x,y));
    vis[x][y] = true;
    dis[t][x][y] = 0;

    while(!q.empty()){
        pair<int,int> x = q.front();q.pop();

        for(int i=0;i<8;i++){
            int xx = x.first  + dir[0][i];
            int yy = x.second + dir[1][i];
            if(xx < 0 || yy < 0 || xx >= 8 || yy >= 8 || vis[xx][yy])continue;
            vis[xx][yy] = true;
            q.push(make_pair(xx,yy));
            dis[t][xx][yy] = dis[t][x.first][x.second] + 1;

        }
    }
}

char str[3];
int main(){
    int T;scanf("%d",&T);
    while(T--){
        for(int i=0;i<3;i++){
            scanf("%s",str);
            bfs(i,str[0]-'A',str[1]-'1');
        }
        int ans = inf;
        for(int i=0;i<8;i++)for(int j=0;j<8;j++){
            ans = min (ans, dis[0][i][j]+dis[1][i][j]+dis[2][i][j]);
        }
        printf("%d\n",ans);
    }
    return 0;
}
版权声明:一个菜逼的笔记,并没有什么题解。。。

hihoCoder hiho一下 第四十二周:骨牌覆盖问题·二

题目1 : 骨牌覆盖问题·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上一周我们研究了2xN的骨牌问题,这一周我们不妨加大一下难度,研究一下3xN的...

【hiho一下 第四十二周】骨牌覆盖问题·二

对于3xN的棋盘,使用1x2的骨牌去覆盖一共有多少种不同的覆盖方法呢?

【hiho一下 第四十一周】骨牌覆盖问题·一

原题地址:http://hihocoder.com/contest/hiho41/problem/1 题目描述 骨牌,一种古老的玩具。今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形...

hiho一(第四十一周)------骨牌覆盖问题·一

题目1 : 骨牌覆盖问题·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具。今天我们要研究的是骨牌的覆盖问题: 我们有一个2x...
  • Han_kin
  • Han_kin
  • 2015年04月13日 18:12
  • 206

hihoCoder 骨牌覆盖问题·一 hiho一下 第四十一周

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述骨牌,一种古老的玩具。今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个...
  • daguge1
  • daguge1
  • 2015年04月18日 16:03
  • 140

HIHO #1162 : 骨牌覆盖问题·三

题目链接这题和之前的一个 状态压缩二,是很类似的,这道题的n比较大,开不下数组,无法使用之前的类似方法,但是由于k比较小,可以使用状态压缩,结合这道题目的前2个版本,考虑使用矩阵快速幂进行计算,关键是...

hihoCoder搜索二---骑士问题---暴力法

题目链接:http://hihocoder.com/problemset/problem/1308直接按照提示给出的方法做,用BFS记录每个骑士到每个点的最小距离,在求所有的最小距离的和最小的点处,得...

hiho一下 第九十八周 题目1 : 搜索一·24点

题目1 : 搜索一·24点 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 周末,小Hi和小Ho都在家待着。 在收...

hiho一下 第五十周 欧拉路·二 (Fleury算法求欧拉路径)

题目1 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实...

hiho欧拉路·二 ----- Fleury算法求欧拉路径

hiho欧拉路·二分析:小Ho:这种简单的谜题就交给我吧!小Hi:真的没问题么?小Ho:啊啊啊啊啊!搞不定啊!!!骨牌数量一多就乱了。小Hi:哎,我就知道你会遇到问题。小Ho:小Hi快来帮帮我!小Hi...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HIHO #1308 : 搜索二·骑士问题
举报原因:
原因补充:

(最多只允许输入30个字)