蓝桥杯-九宫重排-bfs+康托展开+逆序数判断
来源:互联网 发布:部落冲突七本满防数据 编辑:程序博客网 时间:2024/06/05 04:14
/* 蓝桥杯-九宫重排 坑点:用map或set记录状态是否被访问过要logn复杂度 需要将一个状态按照康托展开,变成一个数字,再用数组记录是否被访问 再优化:对于一个九宫格,去掉空格那格,若两状态的逆序数奇偶性不同,则无法互相到达 证明:通过12345678.状态上下左右移动空格,计算逆序数的增减情况,可以知道上下左右移动 操作的逆序数改变都是偶数,所以,对于一个偶逆序数,不可能到达一个奇逆序数的状态 当然,在这题中,这个优化并没起到多大作用,可能数据量比较若吧*/#include<stdio.h>#include<string>#include<string.h>#include<queue>#include<iostream>using namespace std;struct Node{ string stat; int step; Node(){} Node(string _stat,int _step):stat(_stat),step(_step){}};//map<string,int> vis;//map 或set会超时int vis[400000 + 5];string s,e;int reNum(string x){ int resum = 0; for(int i = 1;i < 9;i++){ if(x[i] == '.') continue; //int tmp = 0; for(int j = 0;j < i;j++){ if(x[j] != '.' && x[j] > x[i]){ //tmp++; resum++; } } //printf("tmp[%d] = %d\n",i,tmp); } //printf("%d\n",resum); return resum;}int conter(string x){ int sum = 0; for(int i = 0;i < 9;i++){ int num = 0; for(int j = i+1;j<9;j++){ if(x[j] < x[i]) num++; } //printf("num = %d\n",num); sum = (sum + num) * ((9 - i - 1) == 0 ? 1 : (9 - i - 1)); } //cout<<"x = "<<x<<endl; //printf("sum = %d\n",sum); return sum;}int change(string &x,int pos,int i){ if(i == 0){ if(pos/3 > 0){ x[pos] = x[pos-3]; x[pos-3] = '.'; return 1; } }else if(i == 1){ if(pos/3 < 2){ x[pos] = x[pos+3]; x[pos+3] = '.'; return 1; } }else if(i == 2){ if(pos%3 > 0){ x[pos] = x[pos-1]; x[pos-1] = '.'; return 1; } }else if(i == 3){ if(pos%3 < 2){ x[pos] = x[pos+1]; x[pos+1] = '.'; return 1; } } return 0;}int bfs(string s){ queue<Node> q; int conter_s = conter(s); vis[conter_s] = 1; q.push(Node(s,0)); while(!q.empty()){ Node ct = q.front(); q.pop(); if(ct.stat == e){ return ct.step; } int pos; for(int i = 0;i <= 9;i++){ if(ct.stat[i] == '.'){ pos = i; break; } } for(int i = 0;i < 4;i++){ string nt = ct.stat; if(change(nt,pos,i)){ int count_nt = conter(nt); if(vis[count_nt] == 0){ vis[count_nt] = 1; q.push(Node(nt,ct.step+1)); } } } } return -1;}int main(){ memset(vis,0,sizeof(vis)); cin>>s; cin>>e; int s_resum = reNum(s); int e_resum = reNum(e); //printf("%d %d\n",s_resum,e_resum); if((s_resum%2) != (e_resum%2)){//若两状态逆序数不一样,则肯定无法到达目标状态 printf("-1\n"); }else{ int ans = bfs(s); printf("%d\n",ans); } return 0;}
阅读全文
0 0
- 蓝桥杯-九宫重排-bfs+康托展开+逆序数判断
- 蓝桥杯 历届试题 九宫重排 (八数码问题--康托展开去重 + bfs搜索)
- 蓝桥杯 历届试题 九宫重排 经典八数码问题 A*算法+康托展开
- 康托展开(逆序数)
- 蓝桥杯 九宫重排(BFS)
- hdu1430(康托展开+BFS)
- 康托展开+bfs-2
- 蓝桥杯 历届试题 九宫重排 BFS Java
- 蓝桥杯-历届试题-九宫重排-BFS+剪枝
- 九宫重排---bfs
- 【BFS瞎搜】九宫重排
- 九宫重排(BFS)
- USACO msquare (BFS+康托展开)
- hdu1430魔板(BFS+康托展开)
- loj 1165(bfs+康托展开)
- 【USACO3.2.5】魔板 康托展开/BFS
- [BFS+康托展开]Hdu 1043 Eight
- hdu 3567 康托展开 +BFS
- 笨方法学习Python-习题43、44
- 一头扎进springboot之访问jsp页面
- Elasticsearch(一)elasticsearch5.3.0版本安装与head插件安装
- oracle的PL/SQL定义类型
- 详细全面了解handler机制
- 蓝桥杯-九宫重排-bfs+康托展开+逆序数判断
- C# 开发Chrome内核浏览器(WebKit.net)
- 为什么我们要切换到Linux?我要怎样切换到Linux?
- 一文看懂如何用贝叶斯解决实际问题
- laravel eloquent 模型关联
- C#和WPF开发中的多线程
- Hbase API
- LWIP使用经验---变态级(好文章)
- 逆向工程