埃及分数The Rotation Game骑士精神——IDA*

IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题。

估价函数设计思路:观察一步最多能向答案靠近多少。

埃及分数

题目大意:

  给出一个分数,由分子a 和分母b 构成,现在要你分解成一系列互不相同的单位分数(形如:1/a,即分子为1),要求:分解成的单位分数数量越少越好,如果数量一样,最小的那个单位分数越大越好。

如:

  19/45 = 1/3 + 1/12 + 1/180;

  19/45 = 1/5 + 1/6 + 1/18;

  以上两种分解方法都要3个单位分数,但下面一个的最小单位分数1/18比上一个1/180大,所以第二个更优。

题解:
dfs直接搜爆炸,因为深度无限。

bfs爆炸,空间不行。

所以,采用有深度限制的,并且不耗费空间的迭代加深搜索。

深度即分数的个数。

配合一下A*思想。

剪枝:

1.每次一步到达小于剩余分数的最小分母。

return b/a+1

2.如果当前可以选择的分数(已经是最大的)*剩下的步数<剩下的分数,return (A*思想)

3.如果只剩最后一步,直接判断能否取到。

对于不能取的处理,开一个数组记录。>1000都可以取的。

分数运算,手推式子。注意约分

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000+5;
ll a,b;
int k,T;
bool fl;
ll ans[N];
ll mem[N];
bool no[N];
int dp;
ll getfirst(ll a,ll b){return b/a+1;
}
bool cmp1(ll s1,ll m1,ll s2,ll m2){//s1/m1 > s2/m2 ?return (ll)s1*m2>(ll)m1*s2;
}
bool cmp2(ll s1,ll m1,ll s2,ll m2){//s1/m1 >= s2/m2 ?return (ll)s1*m2>=(ll)m1*s2;
}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;
}
void sub(ll &s1,ll &m1,ll s2,ll m2){s1=s1*m2-s2*m1;m1=m1*m2;ll g=gcd(s1,m1);s1/=g;m1/=g;
}
bool better(){for(int i=dp;i>=dp;i--){if(mem[i]!=ans[i]){//cout<<mem[i]<<" "<<ans[i]<<endl; return (ans[i]==0)||(mem[i]<ans[i]);} } return false;
}
void dfs(int now,ll lim,ll rs,ll rm){//if(dp<4) cout<<now<<" "<<lim<<" "<<rs<<" "<<rm<<endl;if(now==dp){if(rs==1){if(rm<lim) return;//if(rm<=1000&&no[rm]) return;fl=true;//cout<<" ok "<<endl;mem[dp]=rm;if(better()){///cout<<"better "<<endl;
                for(int i=1;i<=dp;i++){
                    //cout<<mem[i]<<" ";
                    ans[i]=mem[i];}//cout<<endl;
            }mem[dp]=0;}return;}lim=max(lim,getfirst(rs,rm));for(int i=lim;;i++){if(cmp1(rs,rm,(dp-now+1),i)) return;if(cmp2(rs,rm,1,i)){ll hs=rs,hm=rm;sub(hs,hm,1,i);mem[now]=i;dfs(now+1,i+1,hs,hm);mem[now]=0;}}
}
int main(){scanf("%lld%lld",&a,&b);int t;for(int i=1;i<=k;i++){scanf("%d",&t);no[t]=1;}fl=false;while(!fl){dp++;//if(dp<4) cout<<dp<<endl;dfs(1,2,(ll)a,(ll)b);}for(int i=1;i<=dp;i++){printf("%lld ",ans[i]);}return 0;
}
View Code

 

The Rotation Game

每次8种选择吃不消。

迭代加深直接做。

A*估价:中间8个数,最多的那一个一次转动最多多一个。如果中间的8个最多的那一个和8的差距比剩余步数多,return

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=9;
int mp[N][N];
int st[N][N];
char sta[10005],top;
char ans[10005],sum;
int dp,num;
bool fl;
int cnt[4];
int fan[9]={0,6,5,8,7,2,1,4,3};
int fin(){cnt[1]=cnt[2]=cnt[3]=0;for(int i=3;i<=5;i++)for(int j=3;j<=5;j++)cnt[mp[i][j]]++;if(cnt[1]==8) return 1;if(cnt[2]==8) return 2;if(cnt[3]==8) return 3;
}
int che(){cnt[1]=cnt[2]=cnt[3]=0;for(int i=3;i<=5;i++){for(int j=3;j<=5;j++){cnt[mp[i][j]]++;}}int big=max(cnt[1],max(cnt[2],cnt[3]));return 8-big;
}
void mvh(int d){if(d==3){int tmp=mp[3][7];for(int i=7;i>=2;i--) mp[3][i]=mp[3][i-1];mp[3][1]=tmp;}else if(d==4){int tmp=mp[5][7];for(int i=7;i>=2;i--) mp[5][i]=mp[5][i-1];mp[5][1]=tmp;    }else if(d==7){int tmp=mp[5][1];for(int i=1;i<=6;i++) mp[5][i]=mp[5][i+1];mp[5][7]=tmp;}else{int tmp=mp[3][1];for(int i=1;i<=6;i++) mp[3][i]=mp[3][i+1];mp[3][7]=tmp;}
}
void mvz(int d){if(d==1){int tmp=mp[1][3];for(int i=1;i<=6;i++) mp[i][3]=mp[i+1][3];mp[7][3]=tmp;}else if(d==2){int tmp=mp[1][5];for(int i=1;i<=6;i++) mp[i][5]=mp[i+1][5];mp[7][5]=tmp;}else if(d==5){int tmp=mp[7][5];for(int i=7;i>=2;i--) mp[i][5]=mp[i-1][5];mp[1][5]=tmp;}else{int tmp=mp[7][3];for(int i=7;i>=2;i--) mp[i][3]=mp[i-1][3];mp[1][3]=tmp;}
}
bool cmp(){for(int i=1;i<=dp;i++){if(sta[i]<ans[i]) return true;if(sta[i]>ans[i]) return false;}return false;
}
void dfs(int now,int las){if(che()>dp-now+1) return;if(now==dp+1){if(che()==0){if(!fl){memcpy(ans,sta,sizeof sta);num=fin();}else if(cmp()){memcpy(ans,sta,sizeof sta);num=fin();}fl=true;}return;}for(int i=1;i<=8;i++){if(i==fan[las]) continue;if((i-1)%4>1) mvh(i);else mvz(i);sta[++top]=i-1+'A';dfs(now+1,i);sta[top--]=' ';if((fan[i]-1)%4>1) mvh(fan[i]);else mvz(fan[i]);}
}
void clear(){dp=0;fl=false;
}
int main(){while(1){clear();scanf("%d",&st[1][3]);//cout<<"aa "<<endl;if(st[1][3]==0) break;scanf("%d",&st[1][5]);scanf("%d%d",&st[2][3],&st[2][5]);for(int i=1;i<=7;i++) scanf("%d",&st[3][i]);scanf("%d%d",&st[4][3],&st[4][5]);for(int i=1;i<=7;i++) scanf("%d",&st[5][i]);scanf("%d%d",&st[6][3],&st[6][5]);scanf("%d%d",&st[7][3],&st[7][5]);memcpy(mp,st,sizeof st);if(che()==0){printf("No moves needed\n");printf("%d\n",fin());continue;}fl=false;while(!fl){dp++;memcpy(mp,st,sizeof st);dfs(1,0);}printf("%s\n",ans+1);printf("%d\n",num);}return 0;
}
View Code

 

骑士精神

也许可以折半爆搜。

但是显然不够漂亮。

明显“超15步-1”,就迭代加深了。

估价函数:每次,骑士最多归位一个。如果算上最后一步的空格,可能归位2个。

所以,当前和终止的差距-1大于剩余步数的话,一定不行。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=6;
int T;
char st[6][6];
int dp;
bool fl;
int nd[6][6]={{0,0,0,0,0,0},{0,1,1,1,1,1},{0,0,1,1,1,1},{0,0,0,2,1,1},{0,0,0,0,0,1},    {0,0,0,0,0,0}
};
int mp[6][6];
int mv[8][2]={{-1,+2},{-1,-2},{-2,+1},{-2,-1},{+1,+2},{+1,-2},{+2,-1},{+2,+1}};
int che(int re){int dif=0;for(int i=1;i<=5;i++){for(int j=1;j<=5;j++){dif+=(mp[i][j]!=nd[i][j]);}}if(dif==0) return 2;return dp-re+1>=dif-1;    
}
void dfs(int now,int x,int y){if(!che(now)) return;if(fl) return;if(now==dp+1){if(che(now)==2) {fl=true;return;}}for(int i=0;i<8;i++){int dx=x+mv[i][0],dy=y+mv[i][1];if(dx<1||dx>5) continue;if(dy<1||dy>5) continue;swap(mp[x][y],mp[dx][dy]);dfs(now+1,dx,dy);swap(mp[x][y],mp[dx][dy]);}
}
void clear(){fl=false;dp=0;
}
int main(){scanf("%d",&T);while(T--){clear();int sx,sy;for(int i=1;i<=5;i++){scanf("%s",st[i]+1);for(int j=1;j<=5;j++){if(isdigit(st[i][j]))mp[i][j]=st[i][j]-'0';else {mp[i][j]=2;sx=i,sy=j;}}}fl=false;for(dp=0;dp<=15;dp++){dfs(1,sx,sy);if(fl) break;}if(fl) printf("%d\n",dp);else printf("-1\n");}return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Miracevin/p/9780322.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[UE4]创建Shooter基类,2种方法

一、可以通过直接修改"BP_FPPCharacter"的名字为“BP_Shooter”作为基类&#xff0c;然后新建一个"BP_FPPCharacter"继承自“BP_Shooter”。 这种方法适用于各个类对"BP_FPPCharacter"依赖不多的情况。 二、创建一个“BP_Shooter”继承于“Chara…

美团扫码付的前端可用性保障实践

开篇 2017年&#xff0c;美团金融前端遇到了很多通用性问题&#xff0c;特别是在保障前端可用性的过程中&#xff0c;我们团队也踩了不少“坑”&#xff0c;在梳理完这些问题以后&#xff0c;我们还专门做了第31期线下沙龙给大家进行了分享。不管是在面试过程中与候选人讨论&a…

Servlet上传文件和下载文件示例

Java Web应用程序中的文件上载和下载以及常见任务。 由于最近我写了很多有关Java servlet的文章 &#xff0c;因此我想提供一个使用servlet上传和下载文件的示例示例。 用例 我们的用例是提供一个简单HTML页面&#xff0c;客户端可以在其中选择要上传到服务器的本地文件。 在提…

用java单源最短路径问题_单源最短路径-贪心算法

单源最短路径&#xff0c;关于这个问题的贪心算有点不好理解&#xff0c;分析后续补充&#xff0c;代码也需要后续优化&#xff0c;便于理解package test;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/*** Created by sa…

APPLE STORE

直接在设置中&#xff0c;使用查看APPLE ID是无法更改的&#xff0c;现在必须要有所在区域的信用卡信息&#xff0c;支付方式无法像以前一样选择“无”。 查询后发现&#xff0c;有人说icloud3.0,即这个旧版的可以进行更改&#xff0c;于是下载。 但发现一个问题&#xff0c;输…

vue项目打包后文本溢出代码消失问题

补充 https://www.cnblogs.com/richard1015/p/8526988.html vue webpack 打包编译-webkit-box-orient: vertical 后消失 解决方案 optimize-css-assets-webpack-plugin这个插件的问题 注释掉webpack.prod.conf.js中下面的代码 new OptimizeCSSPlugin({cssProcessorOptions: c…

前端图片canvas,file,blob,DataURL等格式转换

最近用到一些图片相关的操作&#xff0c;记录一下笔记。 将file转化成base64 场景&#xff1a; 获取到一个file类型的图片&#xff0c;如果直接在html中预览&#xff1f;这里就是利用html5的新特性&#xff0c;将图片转换为Base64的形式显示出来。有两种方法&#xff1a; 方法…

java创建异步多线程_Java创建多线程异步执行实现代码解析

实现Runable接口通过实现Runable接口中的run()方法public class ThreadTest implements Runnable {public static void main(String[] args) {Thread thread new Thread(new ThreadTest());thread.start();}Overridepublic void run() {System.out.println("Runable 方式…

Java中的状态设计模式–示例教程

状态模式是行为设计模式之一 。 当对象根据其内部状态更改其行为时&#xff0c;将使用状态设计模式。 如果必须根据对象的状态更改其行为&#xff0c;则可以在对象中使用状态变量&#xff0c;并使用if-else条件块根据状态执行不同的操作。 状态模式用于通过上下文和状态实现提…

JS 循环遍历 总结

一、循环遍历语句 for...in... &#xff08;ES5&#xff09; 语法&#xff1a;javascript for(keys in obj){}适用&#xff1a;遍历对象说明&#xff1a;   1.keys表示obj对象的每一个键值对的键(键名)&#xff0c;所有循环中&#xff0c;需要使用obj[keys]来取到每一个值。 …

java之平台无关

java虚拟机是执行字节码文件&#xff08;.class&#xff09;的虚拟机进程。 java源程序&#xff08;.java&#xff09;被编译器编译成------>字节码文件&#xff08;.class&#xff09;,然后字节码文件&#xff0c;将由java虚拟机&#xff0c;解释成------>机器码&#x…

适用于ActiveMQ 5.9的Apache Camel Broker组件

将Apache Camel嵌入ActiveMQ代理可以为使用Camel的集成功能扩展消息代理提供极大的灵活性。 Apache Camel路由的另一个好处是&#xff0c;如果使用activemq组件 &#xff0c;则可以避免远程连接到ActiveMQ的序列化和网络开销。 关于Apache ActiveMQ真正伟大的事情之一是&#x…

java rpg对战_RpgGame.java

import java.util.Scanner;public class RpgGame {public static void main(String[] args) {System.out.println("--------------------亲爱的勇士欢迎来到文字世界--------------------");System.out.println("--------------------这是一个充斥着危险的世界&…

hive基本操作与应用

通过hadoop上的hive完成WordCount 启动hadoop Hdfs上创建文件夹 上传文件至hdfs 启动Hive 创建原始文档表 导入文件内容到表docs并查看 用HQL进行词频统计&#xff0c;结果放在表word_count里 查看统计结果 转载于:https://www.cnblogs.com/cairuiqi/p/9048256.html

python - classs内置方法 solt

solt # __solt__ # 是一个类变量,变量值可以是列表、元组或者是可迭代对象,也可以是一个字符串 # (以为这所有实例只有一种数据属性) # # 作用:(为了节省内存空间,减少过多的实例属性所占用的内存空间) # 优点: # 1.使用_solt__以后,实例的__dict__属性被去除,从而达到节省…

如何优雅的链式取值之 MayBe 函子

本文基于 如何优雅地链式取值 可能有人之前看过我写的关于函数式编程的东西&#xff0c;也有人看过这一篇文章。由于我还是学生&#xff0c;开发经验相对较少&#xff0c;所以对于函数式编程如何应用存在一些疑惑。之前也问过面试官&#xff0c;说是实际开发中用的比较少&#…

Jackson中的自定义反序列化器和验证

tl; dr&#xff1a;将输入验证添加到Jackson中的自定义json解串器很重要。 在RHQ中&#xff0c;我们在几个地方使用了Json解析-直接在as7 / Wildfly插件中&#xff0c;或者通过RESTEasy 2.3.5间接在REST-api中使用&#xff0c;已经很繁重了。 现在&#xff0c;我们有一个bean…

java ssh shell命令_java 通过ssh 执行命令

java 里面的开源 ssh libjsch 例子JSch jSch new JSch();//设置JSch 的日志&#xff0c;可以看到具体日志信息JSch.setLogger(new Logger() {Overridepublic boolean isEnabled(int level) {return true;}Overridepublic void log(int level, String message) {System.out.pri…

标准易语言学习

1、窗口程序加入自定义局部变量 按CTRLL弹出局部变量表&#xff08;或点菜单栏上的插入&#xff0c;选择局部变量&#xff09;转载于:https://www.cnblogs.com/slyzly/articles/9048724.html

c# TCP高性能通信

开篇都是吹牛逼哈。。。 我原本打算使用dotnetty来解决传输问题&#xff0c;但是试了下没有成功&#xff0c;也没有找到相关问题解决方法&#xff0c;导出源码&#xff0c;好大啊。暂时不想研究&#xff0c;而且是.Net Core的。最后没有办法&#xff0c;就自己封装了。我就不上…