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循环,把每两个数都判断一遍,判断的要求就是一正一负,绝对值相加是素数,然后还要分情况放左边还是右边,我花的时间主要是在写插入函数那里,具体思路看代码实现(画图找规律是王道啊)。一开始你得判断几个特殊情况。

 #include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define MAXN 40322
#define SIZE 8
using namespace std; typedef int State[SIZE];
typedef struct Status{
State value;
}Status; queue<Status>queuing; int st[MAXN];
bool visit[MAXN];
bool Prime[*SIZE];
int factory[] = {, , , , , , , , };
int start = -;
int dir[] = {, -};
int input[SIZE]; void getPrime()
{//存储需要的素数
memset(Prime, false, sizeof(Prime));
for(int i=; i<*SIZE; ++i)
{
if(!Prime[i])
{
for(int j=i+i; j<*SIZE; j += i)
Prime[j] = true;
}
}
return;
} int try_to_insert(int s[])
{//返回对应的康托展开
int sum = ;
for(int i=; i<SIZE; ++i)
{
int cnt = ;
for(int j=i+; j<SIZE; ++j)
if(fabs(s[i])>fabs(s[j])) ++cnt;
sum += cnt*factory[SIZE-i-];
}
return sum;
} bool isExchange(int a, int b)
{//判断两个对应的数能否插入,可以返回true否则false if((a> && b<) || (a< && b>))
{
if(a>) b = -b;
else a = -a;
if(!Prime[a+b]) return true;
}
return false;
} void Translate(int s[], int to, int from, int kind)
{//插入的函数,kind = -1 表示from位置的数插入到to位置的左边,kind = 1 表示插入到to位置的右边
State p;
int temp_to = s[to], temp_from = s[from];
bool flag = false;
s[to] = s[from] = ;
if(kind == -)
{
for(int i=SIZE-, j=SIZE-; i>=; )
{
if(s[j] != ) p[i--] = s[j--];
else if(flag == false)
{
if(to > from)
{
p[i--] = temp_to;
p[i--] = temp_from;
}
j--;
flag = true;
}
else
{
if(to < from)
{
p[i--] = temp_to;
p[i--] = temp_from;
}
j--;
}
}
}
else
{
for(int i=, j=; i<SIZE; )
{
if(s[j] != ) p[i++] = s[j++];
else if(flag == false)
{
if(to < from)
{
p[i++] = temp_to;
p[i++] = temp_from;
}
j++;
flag = true;
}
else
{
if(to > from)
{
p[i++] = temp_to;
p[i++] = temp_from;
}
j++;
}
}
}
memcpy(s, p, sizeof(p));
return;
} bool Traverse()
{
memset(visit, false, sizeof(visit));
visit[start] = true;
st[start] = ;
Status init;
memcpy(init.value, input, sizeof(input));
queuing.push(init);
while(!queuing.empty())
{
Status ss = queuing.front();
State& s = ss.value;
int elem = try_to_insert(s);
queuing.pop();
//两个for循环加上两种插入的情况
for(int i=; i<SIZE; ++i)
{
for(int j=; j<SIZE; ++j)
{
if(isExchange(s[i], s[j]))
{
Status tt;
State& t = tt.value;
for(int z=; z<; ++z)
{
memcpy(t, s, sizeof(t));
if(i+dir[z] != j)
{
Translate(t, i, j, dir[z]);
int step = try_to_insert(t);
if(!visit[step])
{
visit[step] = true;
st[step] = st[elem]+;
queuing.push(tt);
if(step == )
{//step == 0 表示到达了已排序的状态则返回
return true;
}
}
}
}
}
}
}
}
return false;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("F:\\test\\input.txt", "r", stdin);
#endif
getPrime();
int T = ;
while(cin>>input[] && input[])
{
int flag = ;
if(input[] > ) flag++; for(int i=; i<SIZE; ++i)
{
cin>>input[i];
if(input[i] > ) flag++;
}
start = try_to_insert(input);
cout<<"Case "<<++T<<": ";
if (start == )
{
cout<<""<<endl;
continue;
}
if (flag == SIZE || !flag)
{
cout<<"-1"<<endl;
continue;
}
if(Traverse()) cout<<st[]<<endl;
else cout<<"-1"<<endl; while(!queuing.empty()) queuing.pop();
}
return ;
}

Uva 11198 - Dancing Digits的更多相关文章

  1. UVA 1341 - Different Digits(数论)

    UVA 1341 - Different Digits 题目链接 题意:给定一个正整数n.求一个kn使得kn上用的数字最少.假设同样,则输出值最小的 思路: 首先利用鸽笼原理证明最多须要2个数字去组成 ...

  2. UVa - 11452 - Dancing the Cheeky-Cheeky

    先上题目: F. Dancing the Cheeky-Cheeky  Context The Cheeky-Cheeky is a new song. They dance it in Mula, ...

  3. UVA题目分类

    题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics ...

  4. uva 993 Product of digits (贪心 + 分解因子)

      Product of digits  For a given non-negative integer number N , find the minimal natural Q such tha ...

  5. UVa 993: Product of digits

    这道题很简单.先将N用2,3,5,7(即10以内的素数)分解因数(需要先特殊判断N不为1),然后将可以合并的因数合并(如2*2合并成4,)这样求得的结果位数会减少,大小肯定会小一些.具体实现见代码. ...

  6. uva 10061 How many zero's and how many digits ?

    How many zeros and how many digits? Input: standard input Output: standard output Given a decimal in ...

  7. How many zero's and how many digits ? UVA - 10061

    Given a decimal integer number you will have to find out how many trailing zeros will be there in it ...

  8. UVA - 10061 How many zero&#39;s and how many digits ?

    n!=x*b^y, 当x为正整数时,最大的y就是n!末尾0的个数了, 把n,b分别拆成素因子相乘的形式: 比如, n=5,b=16 n=5,b=2^4, 非常明显,末尾0的个数为0 10进制时,n!= ...

  9. UVA 10061 How many zero's and how many digits ? (m进制,阶乘位数,阶乘后缀0)

    题意: 给出两个数字a和b,求a的阶乘转换成b进制后,输出 (1)后缀中有多少个连续的0? (2)数a的b进制表示法中有多少位? 思路:逐个问题解决. 设a!=k.  k暂时不用直接转成b进制. (1 ...

随机推荐

  1. Android Handler传递参数动态更新UI界面demo

    package com.example.demo_test; import android.app.Activity; import android.os.Bundle; import android ...

  2. 嵌入式控制(0)----linux系统网络配置

    嵌入式系统本身具有操作系统的全部属性,但收到其硬件条件制约,故需要主机通过串口/网口等方式与其通信.今日下午的工作主要是linux系统的ssh传输配置,nfs服务器配置,tftp服务器配置. ip的概 ...

  3. Apple开发者账号申请学习方式

    http://jingyan.baidu.com/article/414eccf610e7c76b431f0a94.html https://developer.apple.com/wwdc/sche ...

  4. iosblock用法

    看了很多的block用法,还是小糊涂. 最后还是自己尝试吧. #import "FirstViewController.h" @interface FirstViewControl ...

  5. jsp中四种传递参数的方法

    jsp中四种传递参数的方法如下: 1.form表单 2.request.setAttribute();和request.getAttribute(); 3.超链接:<a herf="i ...

  6. 预定义的类型“Microsoft.CSharp.RuntimeBinder.Binder”未定义或未导入

    http://www.mzwu.com/article.asp?id=3611 因为新加了Microsoft.CSharp的引用, 只需要重新生成一下项目,就可以消除这个错误提示

  7. CFF前端沙龙总结

    一. -OOCSS + Sass ——大漠 1. OOCSS 结构<=>皮肤 分离 容器<=>内容 分离 2. Sass 工具.处理器 SCSS(CSS风格)<=> ...

  8. MasterPage的自身Bug还是?

    如果不想每个页面都设置css样式,那就在MasterPage设置即可,但是有个问题就是路径并不能识别正确,所以必须让你的页面和MasterPage的页面在平级的位置. 例如MasterPage.mas ...

  9. listagg 函数

    listagg 函数--oracle 11g release 2 转载:http://xpchild.blog.163.com/blog/static/10180985920108485721969/ ...

  10. 通过AJAX与ASP.NET结合实现的仿GridView增删改查功能

    jQurey代码部分: 1.    <script type="text/javascript"> 2.            var flag = 0; 3. 4.  ...