16哈理工新生赛 E Nine Digits (BFS+康拓展开)
来源:互联网 发布:软件著作权 开源代码 编辑:程序博客网 时间:2024/05/21 10:18
题目链接:点击打开链接
Nine DigitsTime Limit: 3000 MSMemory Limit: 32768 KTotal Submit: 69(19 users)Total Accepted: 16(12 users)Rating: Special Judge: NoDescriptionInput
Nine DigitsTime Limit: 3000 MSMemory Limit: 32768 KTotal Submit: 69(19 users)Total Accepted: 16(12 users)Rating: Special Judge: NoDescriptionInput
多组数据,每组测试数据输入9个整数,为1-9的一个全排列。初始状态会被描述为
1 2 3 4 5 6 7 8 9
Output输出所需要的最小移动步数。
Sample Input1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1
0
12
题解:
一看题目,我就想到BFS,就是把所有情况搜出来,也就是9的阶乘362880种情况。但是由于不能够建立一个九位数的数组来保存这些数据,因此这里需要用到康托展开。
康托展开的使用范围是对于n个数的排列进行状态的压缩和存储,例如要对9的全排列进行判重.没有必要开一个10的9次幂的数组,因此它有362880中情况。因此其思想就是相当于一个哈希函数。一个排列它所对应的位置就是它排的是第几大。比如321,对应的值就是6,因为前面有123,132,213,231,312比它小。下面的cantor( )函数就是。
做完康托展开后,就要实现四种情况的变换,这个也比较简单,使用四个函数来实现即可,但是写的过程需要特别小心。
AC代码:
#include<iostream>#include<cstdio>#include<queue>using namespace std;const int MAX=362880;int s[9]={1,10,100,1000,10000,100000,1000000,10000000,100000000};int jie[10]={0,1,2,6,24,120,720,5040,40320,362880};int visit[MAX];int len[MAX];int four[4];int lu(int num){ int result; result=num%s[4]; result+=((num/s[5])%10)*s[4]; result+=num/s[8]*s[5]; result+=((num/s[6])%10)*s[6]; result+=((num/s[4])%10)*s[7]; result+=((num/s[7])%10)*s[8]; return result;}int ru( int num ) { int result = num/s[5]*s[5]; result += num/s[1]%10; result += num/s[4]%10*s[1]; result += num/s[2]%10*s[2]; result += num%10*s[3]; result += num/s[3]%10*s[4]; return result; } int ld( int num ) { int result = num/s[6]*s[6] + num%10; result += num/s[2]%10*s[1]; result += num/s[5]%10*s[2]; result += num/s[3]%10*s[3]; result += num/s[1]%10*s[4]; result += num/s[4]%10*s[5]; return result; } int rd( int num ) { int result = num % s[3] + num/s[8]*s[8]; result += num/s[4]%10*s[3]; result += num/s[7]%10*s[4]; result += num/s[5]%10*s[5]; result += num/s[3]%10*s[6]; result += num/s[6]%10*s[7]; return result; } int cantor(int key) //康拓展开 { int result,temp[9]; for(int i=8;i>=0;i--) { temp[i]=key%10; key=key/10; } result=0; for(int i=0;i<8;i++) { int tot=0; for(int j=i+1;j<9;j++) if(temp[j]<temp[i]) tot++; result+=tot*jie[8-i]; } return result;}int key2[4];int start=123456789;queue<int>que;int main(){ int temp; int key1; len[0]=0; que.push(start); visit[0]=1; while(!que.empty()) { temp=que.front(); que.pop(); key1=cantor(temp); four[0]=lu(temp); four[1]=ru(temp); four[2]=ld(temp); four[3]=rd(temp); for(int i=0;i<4;i++) { key2[i]=cantor(four[i]); if(!visit[key2[i]]) { visit[key2[i]]=1; que.push(four[i]); len[key2[i]]=len[key1]+1; } } } int input[9]; while(~scanf("%d",&input[0])) { temp=input[0]; for(int i=1;i<9;i++) { scanf("%d",&input[i]); temp=input[i]+temp*10; } printf("%d\n",len[cantor(temp)]); } return 0;}
3 0
- 16哈理工新生赛 E Nine Digits (BFS+康拓展开)
- 16哈理工新生赛 J Another Tree (树上BFS)
- 16哈理工新生赛 C 方方正正 (证明题)
- 16哈理工新生赛 I 行编辑器 (模拟)
- 16哈理工新生赛 H 下雪啦 (哈希表)
- 16哈理工新生赛 A 棋盘村 (dp)
- sicily 2011. Nine Digits(广搜,康托展开)
- 16哈理工新生赛 B 修建传送门 (双指针)
- 16哈理工新生赛 G FBI Tree (模拟二叉树后序遍历)
- 16哈理工新生赛 K 小明和字符串(水题)
- 16哈理工新生赛 D 陈月亮的数学题 (数论)
- 哈理工新生赛热身赛解题报告
- POJ 1077 Eight(康拓展开 BFS 双向BFS)
- hdu1043 bfs 康拓展开
- Nine Digits Expression
- sicily 2011 Nine Digits
- 2011. Nine Digits
- Sicily 2011. Nine Digits
- 用函数实现strcmp
- 150. Evaluate Reverse Polish Notation
- 简单化搭建 Docker 数据中心
- python+selenium(环境的安装)
- 读者写者算法
- 16哈理工新生赛 E Nine Digits (BFS+康拓展开)
- 2048(游戏)
- 初识面向对象
- Linux编译内核(4.2.6)并添加系统调用
- 十一个顶级的Git 客户端,绝对很实用!
- log4j日志配置文件log4j.properties
- Freeline - Android平台上的秒级编译方案
- Python随机生成均匀分布在三角形内(或者任意多边形内)的点
- 什么是左连接,右连接,内连接和全连接