Uva 11198 - Dancing Digits
Problem D
Dancing Digits
题目意思:
给你{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 }

更多内容请关注个人微信公众号 物役记 (微信号:materialchains)
作者:雪影蓝枫
本文版权归作者和博客园共有,欢迎转载,未经作者同意须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?