Light OJ 1165

题目链接


题意:
有一个1~8的排列,正数表示男,负数表示女,可以将男的放在女的左右,也可以将女的放到男的左右,但是必须满足两个数的绝对值之和是一个素数,问最少需要进行几次操作,才能使得序列变得递增有序。

思路:
BFS状态结点是一个排列和时间,枚举每一种可能,最先出现的是答案。
状态标记数组开不了,使用set

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <math.h>
#include <bitset>
#include <ctype.h>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-9;
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
int t, kase = 0;

set<int> s;
int a[10];
int A[10];
struct Node
{
    int a[10];
    int t;
    Node(){}
    Node(int *B, int T)
    {
        for(int i = 0; i < 8; i++)
            a[i] = B[i];
        t = T;
    }
};
int Hash(int* A)
{
    int ret = 0;
    for(int i = 0; i < 8; i++)
        ret = ret*10 + abs(A[i]);
    return ret;
}
bool inHash(int tmp)
{
    return s.count(tmp);
}
bool isprime(int x)
{
    if(x == 1) return false;
    for(int i = 2; i <= (int)sqrt(x); i++)
        if(x % i == 0) return false;
    return true;
}
bool judgeSorted(int *A)
{
    for(int i = 0; i < 8; i++)
    {
        if(abs(A[i]) != i+1) return false;
    }
    return true;
}
int bfs()
{
    queue<Node> Q;
    s.clear();
    Node st(a,0);
    Q.push(st);
    int tmp = Hash(a);
    s.insert(tmp);
    while(!Q.empty())
    {
        Node u = Q.front(); Q.pop();
        if(judgeSorted(u.a))
        {
            return u.t;
        }
        for(int i = 0; i < 8; i++)
        {
            for(int j = 0; j < 8; j++)
            {
                if(i == j) continue;
                if(u.a[i]*u.a[j] > 0) continue;
                if(!isprime(abs(u.a[i]) + abs(u.a[j]))) continue;

                Node v;
                int index;
                for(int k = 0, p = 0; k < 7; k++,p++)
                {
                    if(k == i) p++;
                    v.a[k] = u.a[p];
                    if(p == j) index = k;
                }
                int tmp = u.a[i];
                // after
                for(int k = 6; k > index; k--)
                {
                    v.a[k+1] = v.a[k];
                }
                v.a[index+1] = tmp;
                v.t = u.t+1;
                int h = Hash(v.a);
                if(!inHash(h))
                {
                    s.insert(h);
                    Q.push(v);
                }
                //before
                v.a[index+1] = v.a[index];
                v.a[index] = tmp;
                v.t = u.t+1;
                h = Hash(v.a);
                if(!inHash(h))
                {
                    s.insert(h);
                    Q.push(v);
                }
            }
        }
    }
    return -1;
}
int main()
{
    scanf("%d", &t);
    while(t--)
    {
        for(int i = 0; i < 8; i++)
        {
            scanf("%d", &a[i]);
        }
        printf("Case %d: %d
", ++kase, bfs());
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Alruddy/p/7514226.html