[搜索] LightOj 1165 - Digit Dancing

Digit Dancing
題意:
給你8個數,他們的絕對值組成一個1~8的一個排列,每次操作允許找到同時滿足下列情況的兩個數ai,aj ,把aiaj ,或者把ajai

  1. aiaj 兩個數一正一負
  2. abs(ai)+abs(aj) 是素數

問最少操作幾次讓這8個數按絕對值遞增排列。
題解:
8!很小,按題意爆搜即可。

#include<bits/stdc++.h>
using namespace std;
struct node{
    int a[10], t;
    node(){ t = 0; for(int i = 1; i < 10; ++i) a[i] = 0; }
    void scan(){ for(int i = 1; i <= 8; ++i) scanf("%d", a+i); t = 0; }
    int hash(){
        int res = 0;
        for(int i = 1; i <= 8; ++i) res = res*10+abs(a[i]);
        return res;
    }
    node movel(int i, int pos){
        node res = *this;
        if(i < pos){
            while(res.a[i+1] != a[pos]) swap(res.a[i+1], res.a[i]), ++i;
        }
        else{
            while(res.a[i+1] != a[pos]) swap(res.a[i-1], res.a[i]), --i;
        }
        return res;
    }
    node mover(int i, int pos){
        node res = *this;
        if(i < pos){
            while(res.a[i-1] != a[pos]) swap(res.a[i+1], res.a[i]), ++i;
        }
        else{
            while(res.a[i-1] != a[pos]) swap(res.a[i-1], res.a[i]), --i;
        }
        return res;
    }
    bool solved(){
        for(int i = 1; i <= 8; ++i){
            if(a[i] != i && a[i] != -i) return 0;
        }
        return 1;
    }
}s;
int prime[50] = {0};
void init(){
    prime[2] = prime[3] = 1;
    for(int i = 5; i < 50; i += 2){
        for(int j = 2; j < i; ++j){
            if(i%j == 0) break;
            if(j == i-1) prime[i] = 1;
        }
    }
}
int bfs(node s){
    queue<node>q;
    set<int>st;
    q.push(s); st.insert(s.hash());
    while(!q.empty()){
        node now = q.front(); q.pop();
        if(now.solved()) return now.t;
        now.t++;
        for(int i = 1; i <= 8; ++i){
            if(now.a[i] > 0) continue; // <0
            for(int j = 1; j <= 8; ++j){
                if(now.a[j] < 0) continue; // >0
                if(!prime[-now.a[i]+now.a[j]]) continue;
                node nex = now.movel(i, j);
                if(st.count(nex.hash()) == 0){
                    q.push(nex);
                    st.insert(nex.hash());
                }
                nex = now.mover(i, j);
                if(st.count(nex.hash()) == 0){
                    q.push(nex);
                    st.insert(nex.hash());
                }
                nex = now.movel(j, i);
                if(st.count(nex.hash()) == 0){
                    q.push(nex);
                    st.insert(nex.hash());
                }
                nex = now.mover(j, i);
                if(st.count(nex.hash()) == 0){
                    q.push(nex);
                    st.insert(nex.hash());
                }
            }
        }
    }
    return -1;
}
int main(){
    init();
    int T, ca = 1;
    scanf("%d", &T);
    while(T--){
        s.scan();
        printf("Case %d: %d\n", ca++, bfs(s));
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章