Uva 11198 - Dancing Digits
Problem D
Dancing Digits
题目意思:
给你{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的更多相关文章
- UVA 1341 - Different Digits(数论)
UVA 1341 - Different Digits 题目链接 题意:给定一个正整数n.求一个kn使得kn上用的数字最少.假设同样,则输出值最小的 思路: 首先利用鸽笼原理证明最多须要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, ...
- UVA题目分类
题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics ...
- uva 993 Product of digits (贪心 + 分解因子)
Product of digits For a given non-negative integer number N , find the minimal natural Q such tha ...
- UVa 993: Product of digits
这道题很简单.先将N用2,3,5,7(即10以内的素数)分解因数(需要先特殊判断N不为1),然后将可以合并的因数合并(如2*2合并成4,)这样求得的结果位数会减少,大小肯定会小一些.具体实现见代码. ...
- 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 ...
- 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 ...
- UVA - 10061 How many zero'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!= ...
- 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 ...
随机推荐
- Android Handler传递参数动态更新UI界面demo
package com.example.demo_test; import android.app.Activity; import android.os.Bundle; import android ...
- 嵌入式控制(0)----linux系统网络配置
嵌入式系统本身具有操作系统的全部属性,但收到其硬件条件制约,故需要主机通过串口/网口等方式与其通信.今日下午的工作主要是linux系统的ssh传输配置,nfs服务器配置,tftp服务器配置. ip的概 ...
- Apple开发者账号申请学习方式
http://jingyan.baidu.com/article/414eccf610e7c76b431f0a94.html https://developer.apple.com/wwdc/sche ...
- iosblock用法
看了很多的block用法,还是小糊涂. 最后还是自己尝试吧. #import "FirstViewController.h" @interface FirstViewControl ...
- jsp中四种传递参数的方法
jsp中四种传递参数的方法如下: 1.form表单 2.request.setAttribute();和request.getAttribute(); 3.超链接:<a herf="i ...
- 预定义的类型“Microsoft.CSharp.RuntimeBinder.Binder”未定义或未导入
http://www.mzwu.com/article.asp?id=3611 因为新加了Microsoft.CSharp的引用, 只需要重新生成一下项目,就可以消除这个错误提示
- CFF前端沙龙总结
一. -OOCSS + Sass ——大漠 1. OOCSS 结构<=>皮肤 分离 容器<=>内容 分离 2. Sass 工具.处理器 SCSS(CSS风格)<=> ...
- MasterPage的自身Bug还是?
如果不想每个页面都设置css样式,那就在MasterPage设置即可,但是有个问题就是路径并不能识别正确,所以必须让你的页面和MasterPage的页面在平级的位置. 例如MasterPage.mas ...
- listagg 函数
listagg 函数--oracle 11g release 2 转载:http://xpchild.blog.163.com/blog/static/10180985920108485721969/ ...
- 通过AJAX与ASP.NET结合实现的仿GridView增删改查功能
jQurey代码部分: 1. <script type="text/javascript"> 2. var flag = 0; 3. 4. ...