• Uva 11198


    Problem D

    Dancing Digits

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=112&page=show_problem&problem=2139

    题目意思:

    给你{1,2,3,4,5,6,7,8}的一个排列,其中每个数带负号或带正号,通过插入的方法将这些数按绝对值从小到大排序,输出插入的最小步数,如果不可能完成输出-1,能否插入的要求是:你要根据其余的一个数嵌入其左边或右边,这个数跟你要插入的数不同符号,且绝对值相加必须得是素数,所以根据一个数为中心你可以插入其左或其右。

    解题思路:

    #BFS+Hash# 哈希选择了康托展开,用队列存储每一个状态,且用visit[对应哈希值]表示是否已访问过。思路清晰 了就好办,主要是看状态转移的时候是怎样一个转移法,首先要顾及每一个数共需要两个for循环,把每两个数都判断一遍,判断的要求就是一正一负,绝对值相加是素数,然后还要分情况放左边还是右边,我花的时间主要是在写插入函数那里,具体思路看代码实现(画图找规律是王道啊)。一开始你得判断几个特殊情况。

      1 #include<iostream>
      2 #include<string>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<queue>
      7 #define MAXN 40322
      8 #define SIZE 8
      9 using namespace std;
     10 
     11 typedef int State[SIZE];
     12 typedef struct Status{
     13     State value;
     14 }Status;
     15 
     16 queue<Status>queuing;
     17 
     18 int st[MAXN];
     19 bool visit[MAXN];
     20 bool Prime[2*SIZE];
     21 int factory[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};
     22 int start = -1;
     23 int dir[] = {1, -1};
     24 int input[SIZE];
     25 
     26 void getPrime()
     27 {//存储需要的素数
     28     memset(Prime, false, sizeof(Prime));
     29     for(int i=2; i<2*SIZE; ++i)
     30     {
     31         if(!Prime[i])
     32         {
     33             for(int j=i+i; j<2*SIZE; j += i)
     34                 Prime[j] = true;
     35         }
     36     }
     37     return;
     38 }
     39 
     40 int try_to_insert(int s[])
     41 {//返回对应的康托展开
     42     int sum = 0;
     43     for(int i=0; i<SIZE; ++i)
     44     {
     45         int cnt = 0;
     46         for(int j=i+1; j<SIZE; ++j)
     47             if(fabs(s[i])>fabs(s[j])) ++cnt;
     48         sum += cnt*factory[SIZE-i-1];
     49     }
     50     return sum;
     51 }
     52 
     53 bool isExchange(int a, int b)
     54 {//判断两个对应的数能否插入,可以返回true否则false
     55 
     56     if((a>0 && b<0) || (a<0 && b>0))
     57     {
     58         if(a>0) b = -b;
     59         else a = -a;
     60         if(!Prime[a+b]) return true;
     61     }
     62     return false;
     63 }
     64 
     65 void Translate(int s[], int to, int from, int kind)
     66 {//插入的函数,kind = -1 表示from位置的数插入到to位置的左边,kind = 1 表示插入到to位置的右边
     67     State p;
     68     int temp_to = s[to], temp_from = s[from];
     69     bool flag = false;
     70     s[to] = s[from] = 0;
     71     if(kind == -1)
     72     {
     73         for(int i=SIZE-1, j=SIZE-1; i>=0; )
     74         {
     75             if(s[j] != 0) p[i--] = s[j--];
     76             else if(flag == false)
     77             {
     78                 if(to > from)
     79                 {
     80                     p[i--] = temp_to;
     81                     p[i--] = temp_from;
     82                 }
     83                 j--;
     84                 flag = true;
     85             }
     86             else
     87             {
     88                 if(to < from)
     89                 {
     90                     p[i--] = temp_to;
     91                     p[i--] = temp_from;
     92                 }
     93                 j--;
     94             }
     95         }
     96     }
     97     else
     98     {
     99         for(int i=0, j=0; i<SIZE; )
    100         {
    101             if(s[j] != 0) p[i++] = s[j++];
    102             else if(flag == false)
    103             {
    104                 if(to < from)
    105                 {
    106                     p[i++] = temp_to;
    107                     p[i++] = temp_from;
    108                 }
    109                 j++;
    110                 flag = true;
    111             }
    112             else
    113             {
    114                 if(to > from)
    115                 {
    116                     p[i++] = temp_to;
    117                     p[i++] = temp_from;
    118                 }
    119                 j++;
    120             }
    121         }
    122     }
    123     memcpy(s, p, sizeof(p));
    124     return;
    125 }
    126 
    127 bool Traverse()
    128 {
    129     memset(visit, false, sizeof(visit));
    130     visit[start] = true;
    131     st[start] = 0;
    132     Status init;
    133     memcpy(init.value, input, sizeof(input));
    134     queuing.push(init);
    135     while(!queuing.empty())
    136     {
    137         Status ss = queuing.front();
    138         State& s = ss.value;
    139         int elem = try_to_insert(s);
    140         queuing.pop();
    141         //两个for循环加上两种插入的情况
    142         for(int i=0; i<SIZE; ++i)
    143         {
    144             for(int j=0; j<SIZE; ++j)
    145             {
    146                 if(isExchange(s[i], s[j]))
    147                 {
    148                     Status tt;
    149                     State& t = tt.value;
    150                     for(int z=0; z<2; ++z)
    151                     {
    152                         memcpy(t, s, sizeof(t));
    153                         if(i+dir[z] != j)
    154                         {
    155                             Translate(t, i, j, dir[z]);
    156                             int step = try_to_insert(t);
    157                             if(!visit[step])
    158                             {
    159                                 visit[step] = true;
    160                                 st[step] = st[elem]+1;
    161                                 queuing.push(tt);
    162                                 if(step == 0)
    163                                 {//step == 0 表示到达了已排序的状态则返回
    164                                     return true;
    165                                 }
    166                             }
    167                         }
    168                     }
    169                 }
    170             }
    171         }
    172     }
    173     return false;
    174 }
    175 
    176 int main()
    177  {
    178      #ifndef ONLINE_JUDGE
    179      freopen("F:\test\input.txt", "r", stdin);
    180      #endif
    181       getPrime();
    182       int T = 0;
    183      while(cin>>input[0] && input[0])
    184      {
    185          int flag = 0;
    186          if(input[0] > 0)  flag++;
    187 
    188         for(int i=1; i<SIZE; ++i)
    189         {
    190             cin>>input[i];
    191             if(input[i] > 0) flag++;
    192         }
    193         start = try_to_insert(input);
    194         cout<<"Case "<<++T<<": ";
    195         if (start == 0)
    196         {
    197             cout<<"0"<<endl;
    198             continue;
    199         }
    200         if (flag == SIZE || !flag)
    201         {
    202             cout<<"-1"<<endl;
    203             continue;
    204         }
    205         if(Traverse()) cout<<st[0]<<endl;
    206         else cout<<"-1"<<endl;
    207 
    208         while(!queuing.empty()) queuing.pop();
    209      }
    210      return 0;
    211  }
  • 相关阅读:
    java 9+版本中,接口的内容总结
    发红包的案例
    java中成员变量和局部变量的区别
    分别使用面向对象和面向过程两个不同的思路编写代码,打印输出一个数组,输出数组的格式:“[10,20,30,40,50]”
    题目要求:不能使用新数组,就用原来的唯一的数组进行反转
    request.getRequestDispatcher()和response.sendRedirect()区别
    Maven是什么
    字符串中的各种方法
    数组中的各种方法
    字符串的模式匹配方法-match-search-repalce
  • 原文地址:https://www.cnblogs.com/liaoguifa/p/3168761.html
Copyright © 2020-2023  润新知