zoukankan      html  css  js  c++  java
  • HDU 1430 魔板

    题目:魔板

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430

    题意:(中文题)

    思路:

      BFS哈希打表+映射

      哇。。好题啊,映射没想到。由于题目是求状态S到状态T的最短路,所以一开始就把打表排除了,后来看题解说可以映射+打表,因为每一步的行动和数字没关系,因此假设给出的是87654321,可以把8当作1,7当作2,。。。,1当作8,然后对T也作相应变化,这样一来,就可以用12345678广搜打表。

    AC代码:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<string>
      4 #include<queue>
      5 #include<iostream>
      6 using namespace std;
      7 #define Mod 1000007    //取模的大小,哈希表的大小...
      8 #define Max 100007     //存放的总数
      9 
     10 class Hash             //手写哈希
     11 {
     12   public:
     13     int hs[Mod];       //哈希值  设定的哈希函数为 原值 % Mod ,所以哈希值有可能是 0 ~ Mod-1
     14     int next[Max];     //链表    存放哈希值相等的一条链,他的大小取决于所有原值的数量
     15     int S[Max];        //存放原值
     16     string V[Max];     //存放原值对应的val值
     17     int H[Max];        //存放所有哈希值
     18     int sn;            //不同原值的数量
     19     int hn;            //不同哈希值的数量
     20     Hash()             //构造函数: 定义Hash类变量时初始化
     21     {
     22       sn=0;
     23       hn=0;
     24       memset(hs, 0, sizeof(hs));
     25     }
     26     void clear()       //清空函数
     27     {
     28       sn=0;
     29       for(int i=0;i<hn;i++)
     30         hs[H[i]]=0;
     31       hn=0;
     32     }
     33     void add(int s, string val) //加入
     34     {
     35       int ha=s%Mod;          //计算哈希值
     36       if(hs[ha]==0)          //如果该哈希值还未出现过
     37       {
     38         H[hn++]=ha;          //将该哈希值记录起来,同时哈希值数量加 1
     39       }
     40       sn++;                  //0 表示结尾,所以从1 开始存,原值数量加 1,特别针对 hs数组
     41       S[sn]=s;               //将原值记录起来
     42       V[sn]=val;
     43       next[sn]=hs[ha];       //原本原值记录位置
     44       hs[ha]=sn;             //最新原值记录位置,如果从0 开始存,就无法判断此时是空还是1个值
     45 
     46       //比如:5 和 10 有一样的哈希值 ,并且 5 和 10 先后加入 那么有:
     47       //5 加入: next[1] = 0; hs[5] = 1; hs[5] 是哈希值为5 的头,表示第一个原值在1的位置
     48       //10加入: next[2] = 1; hs[5] = 2; 表示第一个哈希值为5的在2,第二个在1,第三个不存在
     49     }
     50     int find(int s)           //查找
     51     {
     52       int ha=s%Mod;     //计算哈希值
     53       int k=hs[ha];          //
     54       while(k!=0)
     55       {
     56         if(S[k]==s) return 1;//找到
     57         k=next[k];           //下一个节点
     58       }
     59       return 0;              //表示没找到
     60     }
     61     string get(int s){
     62       int ha=s%Mod;     //计算哈希值
     63       int k=hs[ha];          //
     64       while(k!=0)
     65       {
     66         if(S[k]==s) return V[k];//找到
     67         k=next[k];           //下一个节点
     68       }
     69       return "";              //表示没找到
     70     }
     71 };
     72 
     73 int change(int s){
     74   return s%10*1000 + s%100/10*100 + s%1000/100*10 + s%10000/1000;
     75 }
     76 
     77 int move(int s, int i){
     78   int gao = s/10000;
     79   int di = change(s%10000);
     80   if(i==1) return di*10000+change(gao);
     81   else if(i==2){
     82     gao = gao/10 + gao%10*1000;
     83     di = di/10 + di%10*1000;
     84   }
     85   else if(i==3){
     86     int tmp1 = gao%1000/10*10;
     87     int tmp2 = di%1000/10*10;
     88     gao -= tmp1;
     89     di -= tmp2;
     90     gao += tmp2/100*100 + tmp1/100*10;
     91     di += tmp2%100/10*100 + tmp1%100/10*10;
     92   }
     93   return gao*10000+change(di);
     94 }
     95 
     96 string get(int i){
     97   if(i==1) return "A";
     98   else if(i==2) return "B";
     99   else return "C";
    100 }
    101 
    102 Hash hs;
    103 queue<int> q;
    104 void bfs(int s){
    105   hs.add(s, "");
    106   q.push(s);
    107   while(q.size()){
    108     int a=q.front();
    109     q.pop();
    110     string ax=hs.get(a);
    111     for(int i=1; i<=3; i++){
    112       int b=move(a, i);
    113 
    114       if(hs.find(b)==0){
    115         hs.add(b, ax+get(i));
    116         q.push(b);
    117       }
    118     }
    119   }
    120 }
    121 
    122 int main(){
    123   bfs(12345678);
    124   int s, t;
    125   while(~scanf("%d%d", &s, &t)){
    126     int c[10], k=1;
    127     for(int i=0; i<8; i++){
    128       c[s/k%10]=8-i;
    129       k=k*10;
    130     }
    131     k=1;
    132     for(int i=0; i<8; i++){
    133       t=t-t/k%10*k+c[ t/k%10 ]*k;
    134       k=k*10;
    135     }
    136 
    137     cout << hs.get(t) << endl;
    138   }
    139   return 0;
    140 }
  • 相关阅读:
    推流当中自适应码率的策略
    使用python实现人脸检测<转载>
    acm.njupt 1001-1026 简单题
    fedora 系统安装后常用设置
    一个普普通通的计算机研究生找工作的感悟
    一个简单的爬虫程序
    HDU 1005 Number Sequence
    【StatLearn】统计学习中knn算法的实验(1)
    SQL描述(2)
    连续点击返回键,退出应用程序
  • 原文地址:https://www.cnblogs.com/hchlqlz-oj-mrj/p/7020193.html
Copyright © 2011-2022 走看看