USACO3.2--Magic Squares+经典搜索

类似于八数码的一道经典搜索题,思路基本也一样.我是用康拓展开进行的判重.

代码如下:

/*
ID: 15674811
LANG: C++
TASK: msquare
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

#define maxn 100000
typedef struct
{
      int a[9];
      int cnt,flag;
}S;
S st[maxn],goal;
int fa[maxn],vis[maxn],fac[10];
char ch[]={‘A‘,‘B‘,‘C‘};
char ans[maxn];

int Hash(S s1)
{
     int code=0;
     for(int i=1;i<9;i++)
     {
          int cnt=0;
          for(int j=i+1;j<9;j++)
              if(s1.a[j]<s1.a[i]) cnt++;
          code+=fac[8-i]*cnt;
     }
     return code;
}

S change(int x,S st)
{
       if(x==0)
       {
            for(int i=1;i<=4;i++)
                 swap(st.a[i],st.a[8-i+1]);
       }
       if(x==1)
       {
            int k=st.a[4];
            for(int i=4;i>1;i--)
                    st.a[i]=st.a[i-1];
            st.a[1]=k;
            k=st.a[5];
            for(int i=5;i<8;i++)
                st.a[i]=st.a[i+1];
            st.a[8]=k;
        }
        if(x==2)
        {
             int k=st.a[3];
             st.a[3]=st.a[2];
             int k1=st.a[6];
             st.a[6]=k; k=k1;
             k1=st.a[7]; st.a[7]=k;
             st.a[2]=k1;
        }
        st.cnt=st.cnt+1;
        st.flag=x;
        return st;
}

int check(S s1)
{
     for(int i=1;i<=8;i++)
        if(s1.a[i]!=goal.a[i])
             return 0;
     return 1;
}

int bfs()
{
       vis[Hash(st[0])]=1;
       int front=0,rear=1;
       while(front<rear)
       {
             S s1=st[front];
            if(check(s1))
                 return front;
             for(int i=0;i<3;i++)
             {
                    S s=change(i,s1);
                    int k=Hash(s);
                    if(vis[k]) continue;
                    vis[k]=1;
                    st[rear]=s;
                    fa[rear]=front;
                    ++rear;
             }
             ++front;
       }
}

void Init()
{
     for(int i=1;i<=maxn;i++)
           fa[i]=i;
     memset(vis,0,sizeof(vis));
     for(int i=1;i<=8;i++)
        st[0].a[i]=i;
    st[0].cnt=0;
}

void print(int x)
{
      int cnt=st[x].cnt;
      int k=0;
      while(1)
      {
           if(x==0) break;
            ans[k++]=ch[st[x].flag];
            x=fa[x];
      }
      printf("%d\n",cnt);
      int j=0;
      for(int i=k-1;i>=0;i--)
      {
                printf("%c",ans[i]);
                j++;
                if(j%60==0&&i!=0)
                    printf("\n");
      }
      printf("\n");
}

int main()
{
      freopen("msquare.in","r",stdin);
      freopen("msquare.out","w",stdout);
      //freopen("in.txt","r",stdin);
      fac[0]=1;
      for(int i=1;i<=8;i++) fac[i]=fac[i-1]*i;
      for(int i=1;i<=8;i++)
           scanf("%d",&goal.a[i]);
      Init();
      int x=bfs();
      print(x);
   return 0;
}
时间: 2024-08-25 15:48:01

USACO3.2--Magic Squares+经典搜索的相关文章

洛谷 P2730 魔板 Magic Squares

P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个正整数来表示.可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列.对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示.这是基本状态. 这里提供三种基本操作,分别用大写字母“

洛谷P2730 魔板 Magic Squares

P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个正整数来表示.可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列.对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示.这是基本状态. 这里提供三种基本操作,分别用大写字母“

魔板 Magic Squares

[题目描述]: 魔板 Magic Squares [思路]: 是不是感觉和八数码有点像? 显而易见的宽搜,把魔板的状态表示为排列,则状态最多有\(8! = 40320\)种,空间是可以接受的,对于是第几个排列可以用康拓展开来实现(我想在做八数码的时候你们都深知这个套路),然后根据题目中的三种方式转移状态,每个状态转移出\(3\)个子状态,注意判重!,一旦目标状态出现,那个所搜索的层数一定是能得到该状态的最小步数.最后就是代码细节多,要仔细. #include<cstdio> #include&

经典搜索题

今天搞了一下传说中的经典搜索题——poj1011,果然里面充斥着各种巧妙的剪枝,做完之后回味一下还是感觉构思太巧妙,所以总结记录一下加深理解. 原题:http://poj.org/problem?id=1011 刚开始接触搜索的初学者面对这道题可能感觉无从下手,即便是告诉了要用深搜解决这道题,也不知道怎么用,我现在也对搜索有了更多的理解与体会,其实不要把搜索只理解为在一个地图上找点,其实搜索更可以抽象为当面对多个选择的时候如何抉择,深搜就是先认准一个方向走下去,不行再回来,走别的路:广搜就是把每

BFS解Magic Squares

Magic Squares IOI'96 Following the success of the magic cube, Mr. Rubik invented its planarversion, called magic squares. This is a sheet composed of 8 equal-sizedsquares: 1 2 3 4 8 7 6 5 In this task we consider the version where each square has a d

840. Magic Squares In Grid (5月27日)

开头 这是每周比赛中的第一道题,博主试了好几次坑后才勉强做对了,第二道题写的差不多结果去试时结果比赛已经已经结束了(尴尬),所以今天只记录第一道题吧 题目原文 Magic Squares In Grid A 3 x 3 magic square is a 3 x 3 grid filled with distinct numbers from 1 to 9 such that each row, column, and both diagonals all have the same sum.

Luogu P2730 魔板 Magic Squares

P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个正整数来表示.可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列.对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示.这是基本状态. 这里提供三种基本操作,分别用大写字母"

【Leetcode_easy】840. Magic Squares In Grid

problem 840. Magic Squares In Grid 参考 1. Leetcode_easy_840. Magic Squares In Grid; 完 原文地址:https://www.cnblogs.com/happyamyhope/p/11214881.html

[LeetCode] 840. Magic Squares In Grid_Easy

A 3 x 3 magic square is a 3 x 3 grid filled with distinct numbers from 1 to 9 such that each row, column, and both diagonals all have the same sum. Given an grid of integers, how many 3 x 3 "magic square" subgrids are there?  (Each subgrid is co