POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)
思路:
这三个题是一个比一个令人纠结呀。
POJ-1077
爆搜可以过,94ms,注意不能用map就是了。
#include<iostream>
#include<stack>
#include<queue>
#include<map>
#include<cstring>
using namespace std;
const int maxn = ;
const int inf = 2.1e9;
const int mod = 1e9+;
const double eps = 1e-; int ans=;
char mp[][]; int Head[maxn];
int viss[maxn];
int Next[maxn];
int tot; bool findd(int n)
{
int s=n%maxn;
int k=Head[s];
while(k!=-){
if(viss[k]==n){return true;}
k=Next[k];
// cout<<k<<endl;
}
tot++;
Next[tot]=Head[s];
viss[tot]=n;
Head[s]=tot;
return false; } int n=;
int a[],k; int mypow(int b)
{
// int s=1;
// for(int i=1;i<=b;i++){
// s*=a;
// }
// return s;
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
// else if(b==9){return 1000000000;}
} inline int cal()
{
int ans=;
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(mp[i][j]=='x'){ans*=;}
else{ans=ans*+mp[i][j]-;}
}
}
return ans;
} int pre[maxn];
char op[maxn]; inline int up(int num)
{
if(k<=){return -;}
int t=k-;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} inline int down(int num)
{
if(k>=){return -;}
int t=k+;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} inline int left(int num)
{
if(k==||k==||k==){return -;}
int t=k-;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} inline int right(int num)
{
if(k==||k==||k==){return -;}
int t=k+;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} void getf(int t)
{
for(int i=;i>=;i--){
a[i]=t%;
t/=;
if(a[i]==){k=i;}
}
} int bfs()
{
queue<int>q;
queue<int>qq;
q.push(cal());
qq.push(-);
int pos=;
int ah;
int ss,num,t;
while(!q.empty()){
num=q.front();
ss=qq.front();
qq.pop();
q.pop();
getf(num);
t=up(num);
if(t==ans){pre[pos]=ss;op[pos]='u';return pos;}
if(t!=-&&!findd(t)){
pre[pos]=ss;
op[pos]='u';
q.push(t);
qq.push(pos);
pos++;
} t=down(num); if(t==ans){pre[pos]=ss;op[pos]='d';return pos;}
if(t!=-&&!findd(t)){
pre[pos]=ss;
op[pos]='d';
q.push(t);
qq.push(pos);
pos++;
} t=left(num);
if(t==ans){pre[pos]=ss;op[pos]='l';return pos;}
if(t!=-&&!findd(t)){
pre[pos]=ss;
op[pos]='l';
q.push(t);
qq.push(pos);
pos++;
} t=right(num);
if(t==ans){pre[pos]=ss;op[pos]='r';return pos;}
if(t!=-&&!findd(t)){
pre[pos]=ss;
op[pos]='r';
q.push(t);
qq.push(pos);
pos++;
}
}
return -;
} int main()
{
ios::sync_with_stdio(false); // while(cin>>)
memset(Head,-,sizeof(Head));
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
cin>>mp[i][j];
}
} if(cal()==ans){cout<<"lr"<<endl;return ;}
int k=bfs();
stack<char>sss;
while(k>){
sss.push(op[k]);
k=pre[k];
}
while(!sss.empty()){
cout<<sss.top();
sss.pop();
}
cout<<endl;
return ;
}
HDU -1043
预处理打表,注意要逆向。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#define fuck(x) /*cout<<#x<<" = "<<x<<endl;*/;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int inf = 2.1e9;
const ll Inf = ;
const int mod = 1e9+;
const double eps = 1e-; int anss=;
int fac[];
void getfac()
{
fac[]=;
for(int i=;i<=;i++){
fac[i]=fac[i-]*i;
}
} int KT(int numi)
{
ll ans=;
int op[];
int s=numi;
for(int i=;i>=;i--){
op[i]=numi%;
// if(op[i]==0){op[i]=9;}
numi/=;
}
for(int i=;i<=;i++){
int sum=;
for(int j=i+;j<=;j++){
if(op[j]<op[i]){sum++;}
}
ans+=sum*fac[-i];
}
// if(ans+1==92307){cout<<"__"<<s<<endl;}
return ans+;
}
int a[],k;
void getf(int t)
{
for(int i=;i>=;i--){
a[i]=t%;
t/=;
if(a[i]==){k=i;}
}
}
int mypow(int b)
{
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
} int up(int num)
{
if(k<=){return num;}
int t=k-;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} int down(int num)
{
if(k>=){return num;}
int t=k+;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} int left(int num)
{
if(k==||k==||k==){return num;}
int t=k-;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} int right(int num)
{
if(k==||k==||k==){return num;}
int t=k+;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} int ans[maxn];
int ord[maxn];
char op[maxn];
struct node
{
int num,s;
};
void bfs()
{
queue<node>q;
q.push(node{anss,});
int pos=;
node exa;
int t,kt;
ans[KT(anss)]=pos;pos++;
while(!q.empty()){
exa=q.front();
q.pop();
int num=exa.num;
getf(num);
fuck(num) t=up(num);
kt=KT(t);
fuck(t)
if(!ans[kt]){
// cout<<"_"<<endl;
ans[kt]=pos;fuck(pos);
fuck(exa.s);
ord[pos]=exa.s;
q.push(node{t,pos});
op[pos]='d';
pos++;
} t=down(num);
fuck(t)
kt=KT(t); if(!ans[kt]){
// cout<<"_"<<endl;
ans[kt]=pos;
fuck(pos);
fuck(exa.s);
ord[pos]=exa.s;
q.push(node{t,pos});
op[pos]='u';
pos++;
} t=left(num);
fuck(t)
kt=KT(t);
if(!ans[kt]){
// cout<<"_"<<endl;
fuck(pos);
fuck(exa.s);
fuck(kt);
ans[kt]=pos;
ord[pos]=exa.s;
q.push(node{t,pos});
op[pos]='r';
pos++;
} t=right(num);
fuck(t)
kt=KT(t);
if(!ans[kt]){
// cout<<"_"<<endl;
ans[kt]=pos;
fuck(pos);
fuck(exa.s);
ord[pos]=exa.s;
q.push(node{t,pos});
op[pos]='l';
pos++;
} }
} char mp[][];
int main()
{
ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
getfac();
int hh=;;
bfs(); // for(int i=1;i<=100;i++){
// cout<<i<<": "<<ord[i]<<
// } for(int i=;i<=;i++){
fuck(ord[i]);
fuck(op[i]);
} while(cin>>mp[][]){
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(i==&&j==){continue;}
cin>>mp[i][j];
}
}
int cnt=;
for(int i=;i<=;i++){
for(int j=;j<=;j++){
if(mp[i][j]=='x'){cnt*=;}
else{cnt=cnt*+mp[i][j]-;}
}
}
// cout<<cnt<<endl;
// cout<<KT(cnt)<<endl;
int kk=ans[KT(cnt)];
if(kk==){printf("unsolvable\n");}
else{
while(kk){
printf("%c",op[kk]);
// cout<<kk<<" "<<op[kk]<<endl;
kk=ord[kk];
}
printf("\n");
}
}
// system("pause");
return ;
}
HDU 3567
这个按顺序预处理,我曾试图使用优先队列,控制一下字典序,但是会超时,看其他的题解都没有这样做,于是我就直接跑,没有管这些了,当然在bfs的时候还是要按照dlru来进行搜索的。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int inf = 2.1e9;
const ll Inf = ;
const int mod = 1e9+;
const double eps = 1e-; int fac[];
void getfac()
{
fac[]=;
for(int i=;i<=;i++){
fac[i]=fac[i-]*i;
}
} int mypow(int b)
{
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
if(b==){return ;}
} int a[],k;
int anss[]={,,,
,,,
,,,}; int up(int num)
{
if(k<=){return num;}
int t=k-;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} int down(int num)
{
if(k>=){return num;}
int t=k+;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} int left(int num)
{
if(k==||k==||k==){return num;}
int t=k-;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} int right(int num)
{
if(k==||k==||k==){return num;}
int t=k+;
num+=a[t]*mypow(-k);
num-=a[t]*mypow(-t);
return num;
} void getf(int t)
{
for(int i=;i>=;i--){
a[i]=t%;
t/=;
if(a[i]==){k=i;}
}
} int KT(int numi)
{
ll ans=;
int op[];
int s=numi;
for(int i=;i>=;i--){
op[i]=numi%;
numi/=;
}
for(int i=;i<=;i++){
int sum=;
for(int j=i+;j<=;j++){
if(op[j]<op[i]){sum++;}
}
ans+=sum*fac[-i];
}
return ans+;
} int ans[][maxn];
int pre[][maxn];
char op[][maxn];
struct node
{
int num,s;
};
void bfs(int ind)
{
queue<node>q;
q.push(node{anss[ind],});
int pos=;
node exa;
int t,kt;
ans[ind][KT(anss[ind])]=pos;pos++;
while(!q.empty()){
exa=q.front();
q.pop();
int num=exa.num;
getf(num);
t=down(num);
kt=KT(t);
if(!ans[ind][kt]){
ans[ind][kt]=pos;
pre[ind][pos]=exa.s;
q.push(node{t,pos});
op[ind][pos]='d';
pos++;
} t=left(num);
kt=KT(t);
if(!ans[ind][kt]){
ans[ind][kt]=pos;
pre[ind][pos]=exa.s;
q.push(node{t,pos});
op[ind][pos]='l';
pos++;
} t=right(num);
kt=KT(t);
if(!ans[ind][kt]){
ans[ind][kt]=pos;
pre[ind][pos]=exa.s;
q.push(node{t,pos});
op[ind][pos]='r';
pos++;
} t=up(num);
kt=KT(t);
if(!ans[ind][kt]){
ans[ind][kt]=pos;
pre[ind][pos]=exa.s;
q.push(node{t,pos});
op[ind][pos]='u';
pos++;
}
}
}
char s1[],s2[]; int numm(char *ss)
{
int ans=;
for(int i=;i<=;i++){
if(ss[i]=='X'){ans*=;}
else ans=ans*+ss[i]-;
}
return ans;
} int change()
{
int pos=;
for(int i=;i<=;i++){
if(s2[i]=='X'){pos=i;}
}
char temp[];
strcpy(temp+,s1+);
int v=;
for(int i=;i<=;i++){
if(s2[i]=='X'){continue;}
v++;
for(int j=;j<=;j++){
if(temp[j]==s2[i]){s1[j]=v+;break;}
}
s2[i]=v+;
}
return pos;
} int main()
{
// ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
getfac();
for(int i=;i<=;i++){
bfs(i);
} int T;
scanf("%d",&T);
int cases=;
while(T--){
scanf("%s%s",s2+,s1+);
cases++;
printf("Case %d: ",cases);
int j=change();
stack<char>q;
int t1,t2;
t1=numm(s1);
int kk=ans[j][KT(t1)];
if(kk==){printf("0\n\n");}
else{
while(kk){
q.push(op[j][kk]);
kk=pre[j][kk];
}
printf("%d\n",q.size());
while(!q.empty()){
printf("%c",q.top());
q.pop();
}
printf("\n");
}
}
return ;
}
POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)的更多相关文章
- ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))
祝大家新年快乐,相信在新的一年里一定有我们自己的梦! 这是一个简化的魔板问题,只需输出步骤即可. 玩具(Toy) 描述 ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具. 该玩具酷似魔方, ...
- ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)
魔板问题,一道经典的康拓展开+BFS问题,为了实现方便,我用string类来表示字符串,此前很少用string类(因为不够高效,而且相对来说我对char数组的相关函数比较熟),所以在这里也发现了很多容 ...
- POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3
http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...
- poj 1077(BFS预处理+康托展开)
Eight Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29935 Accepted: 13029 Special ...
- 【HDOJ3567】【预处理bfs+映射+康拓展开hash】
http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others) Me ...
- HDU 1043 Eight(双向BFS+康托展开)
http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...
- BFS(八数码) POJ 1077 || HDOJ 1043 Eight
题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...
- hdu 1043 Eight(双向bfs)
题意:经典八数码问题 思路:双向bfs ps:还有a*算法(还不会)等解法. 代码: #include<iostream> #include<stdio.h> #include ...
- hdoj1043 Eight(逆向BFS+打表+康拓展开)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 思路: 由于自己对康拓展开用的太少,看到这个题没想到康拓展开,最开始打算直接转换为数字,但太占内 ...
随机推荐
- IntelliJ IDEA详情
详情请参考http://www.phperz.com/article/15/0923/159043.html
- OSError: mysql_config not found
使用Python3开发一个管理平台,用MySQL数据库存放元数据.使用pip安装mysqlclient模块时出现“OSError: mysql_config not found”错误. 解决: # a ...
- windows 安装tensorflow
原文知乎:https://zhuanlan.zhihu.com/p/25778703 前言 看到Rstudio中开始支持Tensorflow,本人是欣喜若狂的,同时TensorFlow官网从16年9月 ...
- 移动APP用例设计中的关键点(转载)
http://www.51testing.com/html/52/n-4421752.html 在测试工作中我们需要不断的总结和储备自己的知识和经验,譬如具备特定属性.环境以及场景,如:PC,手机,智 ...
- 解析$(this).data('type');
html: <button type="button" class="layui-btn layui-btn-sm" data-type="ad ...
- MySQL 5.7 关闭严格模式
If your app was written for older versions of MySQL and is not compatible with strict SQL mode in My ...
- .net core compatibility windows & windows compatible Linux
Who is this package for? This package is meant for developers that need to port existing .NET Framew ...
- GitHub大佬:供计算机学习鉴黄功能的图片数据库
ps:学无止境 想要构建一套鉴黄系统,必须有大量的真实图片供计算机进行学习,以便于区分开正常图片和黄色图片. 近期有位加拿大程序员在Github上传了图片列表,里面包含了大量图片地址可以供计算机进行学 ...
- linux查找符合条件的文件并删除
找到根目录下所有的以test开头的文件并把查找结果当做参数传给rm -rf命令进行删除: 1.find / -name “test*” |xargs rm -rf 2.find / -name “te ...
- Sum of Consecutive Prime Numbers POJ - 2739 线性欧拉筛(线性欧拉筛证明)
题意:给一个数 可以写出多少种 连续素数的合 思路:直接线性筛 筛素数 暴力找就行 (素数到n/2就可以停下了,优化一个常数) 其中:线性筛的证明参考:https://blog.csdn.net ...