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. python--命令(各个模块的安装)

    python命令行 退出python命令行:exit() 安装pymysql pip install pymysql 安装request pip install requests 1.安装django ...

  2. less 经典范例 bootstrap 的 less 版本 常用 less 代码

    1. bootstrap 的 less 版本 2.less 文件分布 /*! * Bootstrap v3.3.7 (http://getbootstrap.com) * Copyright 2011 ...

  3. 第十篇.1、python并发编程之多进程理论部分

    一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的任务,写书的任 ...

  4. linux工具之pmap

    1.pmap简介 pmap命令用来报告一个进程或多个进程的内存映射.可以使用这个工具确定系统是如何为服务器上的进程分配内存的.   例如查看ssh进程的内存映射:  

  5. 用户模式构造-简单自旋锁(SpinLock)

    internal sealed class SimpleSpinLock { //0等于false(默认),1等于true ; public void Enter() { while (true) { ...

  6. MSSQL日期分组排序

    等于今天日期的排上面,大于今天的排中间,小于今天的排下面,带分页.

  7. [CF 1238F] The Maximum Subtree 树DP

    题意 给定一颗树,求这个树的最大子树,且这个子树是一个good-tree. good-tree的定义是:每个节点可以表示成一个数值区间,而树上的边表示两个点表示的数值区间相交. 题解 通过分析可以发现 ...

  8. Java 实现《编译原理》中间代码生成 -逆波兰式生成与计算 - 程序解析

    Java 实现<编译原理>中间代码生成 -逆波兰式生成与计算 - 程序解析 编译原理学习笔记 (一)逆波兰式是什么? 逆波兰式(Reverse Polish notation,RPN,或逆 ...

  9. (转载)搜索引擎的Query自动纠错技术和架构详解

    from http://www.52nlp.cn/%E8%BE%BE%E8%A7%82%E6%95%B0%E6%8D%AE%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E7 ...

  10. count(列) count(*)

    总结:但是真的结论是这样的么.其实不然.其实在数据库中count(*)和count(列)根本就是不等价的,count(*)是针对于全表的,而count(列)是针对于某一列的,如果此列值为空的话,cou ...