T1_挖地雷(提交文件bomp.cpp

递推大法好啊

题解

递推高级题目

这个题就是按照扫雷的思路解决

相邻的三个格子上的雷数和加起来正好等于中间格子上的数

所以当我们确定了第一个格子周围的雷,其余的就都好解决了

注意不好确定的是当第一个格子的数字为1时候,可以在第一个格子上放雷,也可以在第二个格子上放雷,这两种情况可能一种有解,另一种无解

PS:今天这题毒瘤的很,首先谴责T1数据点18:2 1 1,答案不唯一啊!!!

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue> using namespace std; inline int read()
{
int ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'') last=ch,ch=getchar();
while(ch>=''&&ch<='') ans=ans*+ch-'',ch=getchar();
if(last=='-') ans=-ans;
return ans;
} int n;
bool flag;
int pan[];
int ans[]; bool dtdfh()
{
for(int i=;i<=n;i++)
{
ans[i+]=pan[i]-ans[i]-ans[i-];
if(ans[i+]<||ans[i+]>) return ; //超额
} if(ans[n+]>) return ; //不该有数字的位置有了数字
else return ; } int main()
{
freopen("bomp.in","r",stdin);
freopen("bomp.out","w",stdout); n=read();
for(int i=;i<=n;i++)
{
pan[i]=read();
if(pan[i]<||pan[i]>||(i==&&pan[i]>)||(i==n&&pan[i]>)) //输入不合法
{
printf("No answer\n");
return ;
}
} //先确定第一个啊
if(pan[]==) { ans[]=ans[]=; }
if(pan[]==) { ans[]=;ans[]=; }
if(pan[]==) { ans[]=ans[]=; } flag=dtdfh(); //递推求解
if(pan[]==&&flag==)
{
ans[]=;ans[]=;
flag=dtdfh();
} if(!flag) //无解
{
printf("No answer\n");
return ;
} else
{
for(int i=;i<=n;i++)
printf("%d ",ans[i]);
} return ;
}

T2_极值问题(提交文件mn.cpp)

打表大法好啊

题解

我说这题是打表找规律发现是斐波那契数列QWQ

打表之后发现 m , n 是不超过k的两个相邻的最大斐波那契数

正解证明斐波那契,感谢这个大佬 “ 寄蜉蝣于天地,渺沧海之一粟 ”

证明一下啦:

首先我们看到题目给出的那个式子:

start:(n2-mn-m22=1

----> : (m2+mn-n22=1

拿出括号里的单独看:    m2+mn-n

m2+mn-n+2n2-2n2+mn-mn

(m+n)2-2n2-mn

(m+n)-n2-n2-mn

(m+n)-(m+n)n - n2

也就是:(n2-mn-m22  ---->   (m+n)-(m+n)n - n2

so,如果我们有一组解 (m,n),那么一定还存在一组解 (n,m+n),所以你发现这就构成了斐波那契数列!!!

递推求解就好了!!!

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue> using namespace std; inline int read()
{
int ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'') last=ch,ch=getchar();
while(ch>=''&&ch<='') ans=ans*+ch-'',ch=getchar();
if(last=='-') ans=-ans;
return ans;
} const int maxn=1e6+;
int k,m,n;
long long feibo[maxn]={,}; int main()
{
freopen("mn.in","r",stdin);
freopen("mn.out","w",stdout);
k=read(); for(int i=;i<=;i++)
{
feibo[i]=feibo[i-]+feibo[i-];
} for(int i=;i<=;i++)
{
if(feibo[i]>k) {
m=i-;
n=i-;
printf("%ld %ld\n",feibo[n],feibo[m]);
return ;
}
} return ;
}

T3_15数码问题(提交文件Puzzle15.cpp)

骗分大法好啊

题解

说人话:编程50步求解15数码

这题数据水,偏分最高60

what is UVA???一个nice的oj

这个题目用到了神奇的 IDA* 算法(崩溃)

感谢百度找到一个大佬--恋恋恋恋吥舍--

链接: 原文:https://blog.csdn.net/baidu_30476939/article/details/53119195

首先了解一下几个概念:

1.逆序对:在一个序列里,如果一个数后面的数比他小,那么他们两个构成一个逆序对

有何用处??判断一下有无解:

把初始矩阵从左到右,从上到下,展成一行,求它的逆序对 (显然目标矩阵的逆序对个数为0)

           于是这里用到一个定理:设初始状态0所在的行数为i,目标状态0所在的行数为j,两者之差的绝对值为k。若k为奇数,则初始矩阵与目标矩阵两个矩阵相应的逆序数的奇偶性相异才有解。若k为偶数,则两个矩阵的逆序数必须相同才有解。不是上述两种情况即为无解。通过初始判定就可以不用搜索就能直接否定无解情况。


转化到这个题上就是,K为奇数,矩阵逆序对数也应为奇数,K为偶数,矩阵逆序对数也应为偶数

2.曼哈顿距离:坐标系中两点  横坐标之差的绝对值+纵坐标的绝对值  之和

有何用处:预估最少步数,预估出来的步数一定是小于等于实际步数的

官方一点就是:求出初始矩阵与目标矩阵对应值得曼哈顿距离并求和(除去0)得到的值为评估值,写成函数即为评估函数。该值为从初始状态到目标状态所要经过的最小步数,实际步数只会大于等于该值。

算法介绍:

这次使用的算法是IDA*。我们首先是用逆序数进行判定是否有解,有解才进行搜索。有解的话,则先得到评估函数的初始值,该值为最小步数,递归深度(步数)必然大于等于这个初始值limit。我们先按深度搜索寻遍该深度的所有情况,看是否能找到解,有解则该解是最优解。若没解,则将深度的限制条件limit加1,再次递归下一层深度的所有情况,有解即为最优解,无解则继续将深度限制条件limit加1,这样不停循环直到某个深度maxLevel,则放弃寻找,因为在maxLevel步中没有找到,继续找下去时间花销太高,故放弃寻找。这就是IDA*中ID的意思,迭代加深。其中,算法在递归中使用了当前递归深度level,用level+评估函数(当前状态到目标状态至少需要的步数)<=limit作为剪枝条件,不满足该条件的在该分支上肯定无解。这样我们就可以找到在maxLevel步以内的最优解。

代码

//15数码问题
#include<iostream>
#include<cstdlib>
#include<cmath>
#define size 4
using namespace std; int move[][]={{-,},{,-},{,},{,}};//上,左,右,下增量
char op[]={'U','L','R','D'};
int map[size][size],map2[size*size],limit,path[];
//limit预估最少步数
int flag,length;
//int goal_st[3][3]={{1,2,3},{4,5,6},{7,8,0}};//目标状态
//goal存储目标位置,即0存在(3,3),1存在(0,0)...
int goal[][]= {{,},{,},{,}, {,},
{,},{,},{,}, {,},
{,},{,},{,}, {,},
{,},{,},{,}, {,}}; int h(int a[size*size])//求逆序数 ,判断有无解
{
int i,j,num,w,x,y; //w记录起点标号
num=; //逆序对数
for(i=;i<size*size;i++)
{
if(a[i]==)
w=i;
for(j=i+;j<size*size;j++)
{
if(a[i]>a[j])
num++;
}
} x=w/size; //起点横坐标
y=w%size; //起点纵坐标 num+=abs(x-)+abs(y-); //9102.9.7 if(num%==)
return ;
else
return ;
} int manhattan(int a[][size])//计算曼哈顿距离,小等于实际总步数
{
int i,j,cost=;
for(i=;i<size;i++)
for(j=;j<size;j++)
{
int w=map[i][j];
cost+=abs(i-goal[w][])+abs(j-goal[w][]);
}
return cost;
} void swap(int*a,int*b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
} void dfs(int sx,int sy,int dep,int pre_move)//sx,sy是空格的位置
{
int i,j,nx,ny;
if(flag)
return;
int dv=manhattan(map);
if(dep==limit)
{
if(dv==)
{
flag=;
length=dep;
return;
}
else
return;
}
else if(dep<limit)
{
if(dv==)
{
flag=;
length=dep;
return;
}
}
for(i=;i<;i++)//4个方向尝试
{
if(i+pre_move==&&dep>)//不和上一次移动方向相反,对第二步以后而言
continue;
nx=sx+move[i][];
ny=sy+move[i][];
if(<=nx && nx<size && <=ny&&ny<size)//如果可以移动
{
swap(&map[sx][sy],&map[nx][ny]);//交换两位置
int p=manhattan(map);
if(p+dep<=limit&&!flag)
{
path[dep]=i;
dfs(nx,ny,dep+,i);
if(flag)
return;
}
swap(&map[sx][sy],&map[nx][ny]);
}
}
} int main()
{
freopen("Puzzle15.in","r",stdin);
freopen("Puzzle15.out","w",stdout);
int i,j,k,l,m,n,sx,sy;
char c,g;
i=;
scanf("%d",&n);
while(n--) //n组数据
{
flag=;length=;
//flag判断有无解 memset(path,-,sizeof(path));
//路径存储数组,记录每一步的抉择,也就是最后要输出的答案
//(数字代码,后边转化成字符串) for(i=;i<;i++)
{
scanf("%d",&map2[i]); //读入15数码图
if(map2[i]==) //寻找0在哪里
{
map[i/size][i%size]=; //记录在图上的位置
sx=i/size;sy=i%size; //记录起点的横纵坐标
}
else
{
map[i/size][i%size]=map2[i]; //记录到图上
}
} if(h(map2)==)//该状态可达
{
limit=manhattan(map);
while(!flag&&length<=)//题中要求50步之内到达
{
dfs(sx,sy,,);
if(!flag)
limit++; //得到的是最小步数
}
if(flag)
{
for(i=;i<length;i++)
printf("%c",op[path[i]]);
printf("\n");
}
}
else if(!h(map2)||!flag)
printf("This puzzle is not solvable.\n");
}
return ;
}

-----在崩溃的边缘疯狂试探-----

2019.7.9 校内交流测试(T 3 待更完)的更多相关文章

  1. 2019.7.9 校内测试 T3 15数码问题

    这一次是交流测试?边交流边测试(滑稽 15数码问题 大家应该都玩过这个15数码的游戏吧,就在桌面小具库那里面哦. 一看到这个题就知道要GG,本着能骗点分的原则输出了 t 个无解,本来以为要爆零,没想到 ...

  2. 2019.7.9 校内测试 T2 极值问题

    这一次是交流测试?边交流边测试(滑稽 极值问题 乍一看这是一道数学题,因为1e9的数据让我暴力的心退却. 数学又不好,不会化简式子嘞,咋办? 不怕,咱会打表找规律.(考场上真的是打表找出了规律,打表打 ...

  3. 2019.7.9 校内测试 T1挖地雷

    这一次是交流测试?边交流边测试(滑稽 挖地雷 这个题是一个递推问题. 首先我们看第一个格子,因为它只影响了它的上面和右上面这两个地方是否有雷. 我们可以分3种情况讨论: 1. 第一个格子的数字是2: ...

  4. 2019第一期《python测试开发》课程,10月13号开学

    2019第一期<python测试开发>课程,10月13号开学! 主讲老师:上海-悠悠 上课方式:QQ群视频在线教学,方便交流 本期上课时间:10月13号-12月8号,每周六.周日晚上20: ...

  5. 2019.8.9 NOIP模拟测试15 反思总结

    日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...

  6. 2019.6.28 校内测试 T4 【音乐会】达拉崩吧·上

    考试的一道附加题~ 一看题目描述:把区间[l,r]里每个数异或上x,求区间[l,r]里所有数的异或和,这明显的要用数据结构或RMQ吧. 恩,所以正解就是线段树啦,至于树状数组行与否,不知道~ wate ...

  7. 2019.6.28 校内测试 T3 【音乐会】道路千万条

    大眼一看最下面的题意解释的话,发现这和洛谷P1310表达式的值挺像的,大概都是给定一些运算符号,让最后的表达式为true的概率,为false的概率啥的QwQ~: 然后这个题嘛?就是在所有的运算符中提溜 ...

  8. 2019.6.28 校内测试 T2 【音乐会】二重变革

    看到这个题之后,一个很暴力很直接的想法就是贴上题目中的代码然后交上去走人,但是很显然这是会TLE+MLE的,想想谁会这么傻把主要代码给你QwQ~: 其实这段代码是想告诉你一件事:用序列中的大数减去小数 ...

  9. 2019.6.28 校内测试 T1 Jelly的难题1

    这题面有点难理解,建议直接跳到题意解释那一部分(虽然我觉得解释的不大对,但按照解释来做确实能AC): 按照“题意解释”的思路来思考这个题,那么就十分的简单了: 1.首先要读入这个字符矩阵,可以用cin ...

随机推荐

  1. new Date,Date.parse()传值

    获取时间: 获取1997年10月1号日期 new Date: 当使用 - 拼接年月日时将会使用UTC时区解析参数,会比北京时间快八小时. 当时用 / 拼接年月日时会使用北京的时区去解析参数,取到的是北 ...

  2. JDK1.8中LinkedList的实现原理及源码分析

    详见:https://blog.csdn.net/cb_lcl/article/details/81222394 一.概述           LinkedList底层是基于双向链表(双向链表的特点, ...

  3. Linux--Shell 编程-bash,命令替换,if分支嵌套,运算,输入输出

    SHELL 编程     shell 是一个命令解释器,侦听用户指令.启动这些指令.将结果返回给用户(交互式的shell)     shell 也是一种简单的程序设计语言.利用它可以编写一些系统脚本. ...

  4. pyquery:轻松、灵活的处理html

    介绍 pyquery是一个专门用来解析html的库,从名字很容易想到jQuery,没错,这完全是仿照jQuery的语法实现的.如果用过jQuery,那么pyquery也很容易上手 初始化html py ...

  5. 华为ensp问题:云映射本地网卡,直连路由器可以ping通,pc却不行?

    拓扑图:cloud 云映射本机物理网卡:192.168.56.1     R1可以Ping通,所有Pc都不行,路由表也存在路由信息,不知道什么问题?

  6. harbor私有仓库

    私有仓库部署在部署节点上 解压此压缩包(压缩包在上篇博文<kubernetes部署中有链接,可下载>) tar xzf harbor-offline-installer-v1.4.0.tg ...

  7. centos8 网卡命令(centos7也可用)

    nmcli n 查看nmcli状态 nmcli n on 启动nmcli nmcli c  up eth0 启动网卡eth0 nmcli c down eth0 关闭网卡eth0 nmcli d c ...

  8. SQL SERVER 查询被锁的表、解锁表

    -- 查询被锁的表select   request_session_id   spid,OBJECT_NAME(resource_associated_entity_id) tableName   f ...

  9. 隔离技术线程池(ThreadPool)和信号量(semaphore)

    一.首先要明白Semaphore和线程池各自是干什么? 信号量Semaphore是一个并发工具类,用来控制可同时并发的线程数,其内部维护了一组虚拟许可,通过构造器指定许可的数量,每次线程执行操作时先通 ...

  10. Summer training round2 #3

    A!:                    GTY系列题 B!:莫队加分块  GTY系列题 C!:线段树模拟拓扑排序(把普通的拓扑排序的栈操作改成线段树区间减一,查询区间最右侧的0的位置即可.注意一 ...