zoukankan      html  css  js  c++  java
  • Vijos 1206 CoVH之再破难关 [BFS] [位运算]

    1.题意:一个由01组成的4*4的矩阵,可以实现相邻元素交换位置的操作,给出初试状态和目标状态,试求最少操作数的方案;

    2.输入输出:输入给出初试矩阵和目标矩阵;要求输出最小操作的次数;

    3.分析:输出最小操作数,很容易联想到使用BFS,这里为了方便表示,把4*4的矩阵拉成一个16个数的数组来看,并用一个16位二进制数表示其状态;用位运算来实现交换某两位的状态,另外再稍微注意一下如何在表示"相邻"的概念即可;

      1 # include <iostream>
      2 # include <cstdio>
      3 # include <queue>
      4 # include <cstring>
      5 using namespace std;
      6 const int MAXN=1<<17;
      7 int vis[MAXN];
      8 int START,END;
      9 int dx[4]={-1,1,4,-4};
     10 void swap(int &a,int &b)
     11 {
     12     int t;
     13     t=a;
     14     a=b;
     15     b=t;
     16 }
     17 struct Node
     18 {
     19     int step,num;
     20     Node(){}
     21     Node(int ss,int nn)
     22     {
     23         step=ss;
     24         num=nn;
     25     }
     26 };
     27 void Init()
     28 {
     29     char M[5][5];
     30     END=START=0;
     31     for(int i=0;i<4;i++)
     32         scanf("%s",M[i]);
     33     for(int i=0;i<4;i++)
     34         for(int j=0;j<4;j++)
     35             START|=((int(M[i][j]-'0'))<<(4*i+j));
     36     for(int i=0;i<4;i++)
     37         scanf("%s",M[i]);
     38     for(int i=0;i<4;i++)
     39         for(int j=0;j<4;j++)
     40             END|=((int(M[i][j]-'0'))<<(4*i+j));
     41     memset(vis,0,sizeof(vis));
     42 }
     43 int change(int i,int j,int n)
     44 {
     45     int nt=n;
     46     int temp=n;
     47     int subi=(n>>i)&1;//取出i位 
     48     int subj=(temp>>j)&1;//取出j位 
     49     swap(subi,subj);
     50     nt&=(((1<<16)-1)^(1<<i)); 
     51     nt&=(((1<<16)-1)^(1<<j));
     52     nt|=(subi<<i);
     53     nt|=(subj<<j);
     54     return nt;
     55 }
     56 void Solve()
     57 {
     58     
     59     int ans=-1;
     60     queue<Node> Q;
     61     Q.push(Node(0,START));
     62     while(!Q.empty())
     63     {
     64         Node temp=Q.front();
     65         Q.pop();
     66         if(temp.num==END)
     67         {
     68             ans=temp.step;
     69             break;
     70         }
     71         for(int i=0;i<16;i++)
     72             for(int j=0;j<4;j++)    
     73             {
     74                 int t=temp.num;
     75                 if(dx[j]==-1||dx[j]==1)
     76                 {
     77                     if((i/4)==((i+dx[j])/4)&&(i+dx[j])>=0&&(i+dx[j])<16)
     78                     {
     79                         int nt=change(i,i+dx[j],t);
     80                         if(!vis[nt])
     81                         {
     82                             Q.push(Node(temp.step+1,nt));
     83                             vis[nt]=1;
     84                         }
     85                     }
     86                 }
     87                 else
     88                 {
     89                     if((i+dx[j])<16&&(i+dx[j])>=0)
     90                     {
     91                         int nt=change(i,i+dx[j],t);
     92                         if(!vis[nt])
     93                         {
     94                             Q.push(Node(temp.step+1,nt));
     95                             vis[nt]=1;    
     96                         }
     97                     }
     98                 }
     99             }
    100     }
    101     printf("%d
    ",ans);
    102 }
    103 int main()
    104 {
    105     //freopen("in.txt","r",stdin);
    106     //freopen("out.txt","w",stdout);
    107     Init();
    108     Solve();
    109     return 0;
    110 } 
  • 相关阅读:
    (转)单机上配置hadoop
    整数划分 Integer Partition(二)
    整数划分 Integer Partition(一)
    深入理解计算机系统:信息的处理和表示(二)整数四则运算
    深入理解计算机系统:信息的处理与表示(一)基础
    从《营造法式》为何成书于北宋 谈起
    (转)排列算法 Permutation Generation
    洛谷2971 [USACO10HOL]牛的政治Cow Politics
    洛谷1549 棋盘问题(2)
    洛谷3084 [USACO13OPEN]照片Photo
  • 原文地址:https://www.cnblogs.com/cnXuYang/p/6664328.html
Copyright © 2011-2022 走看看