vis

骑士问题

匿名 (未验证) 提交于 2019-12-02 23:47:01
题目 题目描述 小明是一名出色的棋手,声称没有人能像他那样快速地把骑士从一个位置移到另一个位置,你能打败他吗? 编写一个程序,计算一个骑士从棋盘上的一个格子到另一个格子所需的最小步数。骑士一步可以移动到的位置由下图给出。 输入 第一行给出骑士的数量 n。对于每一个骑士都有3行,第一行一个整数 L 表示棋盘的大小(4≤L≤300),整个棋盘大小为 L×L; 第二行和第三行分别包含一对整数 (x,y),表示骑士的起始点和终点。假设对于每一个骑士,起始点和终点均合理。 输出 对每一个骑士输出一行,一个整数表示需要移动的最小步数。如果起始点和终点相同,则输出 0。 样例输入 3 8 0 0 7 0 100 0 0 30 50 10 1 1 1 1 样例输出 5 28 0分析这道题是一道广搜题,用深搜可能会时间超限。这道题难度也不低,代码很长,需要用到队列queue代码 #include<bits/stdc++.h> using namespace std; bool vis[301][301]; int step[301][301],ans,t,n,sx,sy,ex,ey,nx,ny; int main() { scanf("%d",&t); while(t--){ scanf("%d%d%d%d%d",&n,&sx,&sy,&ex,&ey); queue<int> qx,qy; qx

洛谷p1605--迷宫 经典dfs

匿名 (未验证) 提交于 2019-12-02 23:47:01
https://www.luogu.org/problemnew/show/P1605 用这种题来复习一下dfs 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。 题目描述 输入输出格式 输入格式: 第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。 输出格式: 给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。 输入输出样例 复制 2 2 1 1 1 2 2 1 2 复制 1 说明 【数据规模】 1≤N,M≤5 最基本的dfs题目,走迷宫。 一开始还出现了一点错误,在判断方案的时候没有先判断终止条件,将计数写在了最前面。 如果终点是障碍物的话没有终止而是计数。 错误代码: #include <stdio.h> #include <iostream> #include <cstdlib> #include <cmath> #include <cctype> #include <string> #include <cstring> #include <algorithm> #include <stack>

【同余最短路】【例题集合】洛谷P3403 跳楼机/P2371 墨墨的等式

匿名 (未验证) 提交于 2019-12-02 23:42:01
接触到的新内容,【同余最短路】。 代码很好写,但思路不好理解。 同余最短路,并不是用同余来跑最短路,而是通过同余来构造某些状态,从而达到优化时间空间复杂度的目的。往往这些状态就是最短路中的点,可以类比差分约束跑最短路( f[i]+w<=f[j] 构造最短路不等式(例题luogu 小k的农场)) ――来自洛谷P3403 Liao_rl 的题解 【P3403跳楼机】 题目背景 DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧。 题目描述 经过改造,srwudi的跳楼机可以采用以下四种方式移动: 向上移动x层; 向上移动y层; 向上移动z层; 回到第一层。 一个月黑风高的大中午,DJL来到了srwudi的家,现在他在srwudi家的第一层,碰巧跳楼机也在第一层。DJL想知道,他可以乘坐跳楼机前往的楼层数。 输入输出格式 输入格式: 第一行一个整数h,表示摩天大楼的层数。 第二行三个正整数,分别表示题目中的x, y, z。 输出格式: 一行一个整数,表示DJL可以到达的楼层数。 输入输出样例 输入样例#1: 15 4 7 9 输出样例#1: 9 输入样例#2: 33333333333 99005 99002 100000 输出样例#2: 33302114671 说明 可以到达的楼层有:1,5,8,9,10,12,13,14,15 想不出来不要死磕这一题,先看看第三题。。。。 1

【LeetCode 210】Course Schedule II

匿名 (未验证) 提交于 2019-12-02 23:39:01
题意: 在判断能否修完全部课程的基础上,如果能,输出任意一个课程顺序。 思路: 递归。在判断是否有环的基础上,记录访问顺序。 代码: class Solution { public : vector < int > findOrder ( int numCourses , vector < vector < int >> & prerequisites ) { vector < vector < int >> graph ( numCourses ) ; for ( auto pre : prerequisites ) { graph [ pre [ 0 ] ] . push_back ( pre [ 1 ] ) ; } vector < int > order ; vector < int > vis ( numCourses , 0 ) ; for ( int i = 0 ; i < numCourses ; ++ i ) { if ( ! vis [ i ] ) { vis [ i ] = 1 ; if ( ! dfs ( i , graph , vis , order ) ) { order . clear ( ) ; return order ; } } } return order ; } bool dfs ( int id , vector < vector <

Knight Moves

元气小坏坏 提交于 2019-12-02 23:18:35
https://loj.ac/problem/10028 题目描述   在一个 \(L×L\) 的棋盘中,给出马的初始位置和终止位置,求最少跳多少步从初始到终止。 思路    \(bfs\) 的模板题,不过为了提高速度我们可以采用双向宽度搜索,分别从起始位置和终止位置进行 \(bfs\) ,在判断何时两个 \(bfs\) 在同一地点相遇即可。为了避免效率过低,我们可以每次选择队列中节点少的进行拓展。 代码 #include <bits/stdc++.h> using namespace std; struct aa { int x,y; }st,ed; int dx[10]={1,1,-1,-1,2,2,-2,-2}; int dy[10]={2,-2,2,-2,1,-1,1,-1}; int dis[3][330][330],l,ans; queue<aa>q[3]; bool vis[3][330][330]; bool expand(int k) { aa now=q[k].front();q[k].pop(); int d=dis[k][now.x][now.y]; for(int i=0;i<8;i++) { aa nex; nex.x=now.x+dx[i];nex.y=now.y+dy[i]; if(nex.x<=0||nex.x>l||nex.y<=0||nex.y

棋盘游戏

萝らか妹 提交于 2019-12-02 23:18:05
https://loj.ac/problem/10029 题目描述   在一个 \(4×4\) 的棋盘上有 \(8\) 个黑棋和 \(8\) 个白棋,当且仅当两个格子有公共边,这两个格子上的棋是相邻的。移动棋子的规则是交换相邻两个棋子。给出一个初始棋盘和一个最终棋盘,请找出一个最短的移动序列使初始棋盘变为最终棋盘,输出最短序列的长度。 思路   数据如此之小,显然是要我们搜索。而这里对棋盘可以直接简单的压缩为一个 \(16\) 位的二进制数,那么显然我们可以很好的存储状态。接下来要考虑的就是如何对当前状态进行拓展。首先我们易知操作世界上只有两种,一是交换左右棋子,二是交换上下棋子,我们只需要用位运算取出每一位的颜色并且判断与之交换的棋子颜色是否相同,再尝试进行两种交换判是否出现过即可。 代码 #include <bits/stdc++.h> using namespace std; bool vis[70000]; int step[70000]; queue<int> q; int main() { int a=0,b=0; char s[5]; for(int i=1;i<=4;i++) { scanf(" %s",s); for(int j=0;j<4;j++) a=a*2+s[j]-'0'; } for(int i=1;i<=4;i++) { scanf(" %s",s);

2-sat

匿名 (未验证) 提交于 2019-12-02 23:05:13
https://www.cnblogs.com/31415926535x/p/10367857.html 2-sat是k-sat问题中k==2时的一种情况,,(废话qaq,, 当k大于等于3时是npc问题,,所以一般都是问的2-sat,, 这种题的大概形式是: 对于给定的n对的点,要求每一对都只能选择一个,并且其中还有一些限制条件,比如说选了u就不能选择v等等,, 然后问你有没有可行解,,, 解决这类问题一般是用 染色法(求字典序最小的解) 和 强连通分量法(拓扑排序只能得到任意解) ,, 首先要明白一个道理:对于 u->v (选择u就不能选择v)这样的限制条件可以用它的逆否命题来转换为: u->v' (选择u就必须选v')以及 v->u' (选择v就必须选u') 最后的建出的图是对称的,, 具体的数学证明和算法推导看这里 和 kuangbin的博客 ,,多看几遍,,跟着敲一遍代码后再看看就差不多懂了 这个算法的大致思路就是遍历每一对点的两种情况:选p或者选p',,, 然后一直从p的下一个尝试下去,,中间若是碰到不能避免的不满足题意的选择时,证明这条路下来的尝试时不行的,,重新选择,,一直下去。。。也就是一个深搜的过程,,时间复杂度大概是 \(O(nm)\) ,, 可以看看这篇博客,, 这个算法的流程为: 建图 求极大联通分量(子图) 缩点,转化成DAG(有向无环图) 判断有无解

【模板】spfa

拥有回忆 提交于 2019-12-02 23:05:05
int dis[maxn]; bool vis[maxn]; queue<int>q; void spfa(int x) { mem(dis, 0x3f); mem(vis, false); dis[x] = 0; q.push(x); vis[x] = true; while (!q.empty()) { int t = q.front(); q.pop(); vis[t] = false; for (Re int i = head[t]; i != -1; i = e[i].nxt) { int u = e[i].u; int w = e[i].w; if (dis[u] > dis[t] + w) { dis[u] = dis[t] + w; if (!vis[u]) { q.push(u); vis[u] = true; } } } } } 来源: https://www.cnblogs.com/thjkhdf12/p/11766338.html

POJ_3013_最短路

左心房为你撑大大i 提交于 2019-12-02 19:56:27
POJ_3013_最短路 Big Christmas Tree Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 23630 Accepted: 5125 Description Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of the tree is shown in right picture. The tree can be represented as a collection of numbered nodes and some edges. The nodes are numbered 1 through n . The root is always numbered 1. Every node in the tree has its weight. The weights can be different from each other. Also the shape of every available edge between two nodes is different, so

20191023+~20191028

独自空忆成欢 提交于 2019-12-02 17:50:55
前言 落下了很久的博客,稍补一下。 由于我的记忆力很差只能记住一天以内的考试,所以n天前的考试我是差不多忘光了。 所以与其说是题解,更不如说坑点总结和吐槽合集…… 20191023+ T1 直接模拟,如何去重应该很好想到。 但是我的确是不知道为什么一个优先队列会比u15个队列慢这么多……logK和15应该差不多啊。 然而事实上我在意淫优先队列每次也要扩展15个点所以复杂度是多了个log。 时间复杂度$\Theta(KB)$,空间复杂度稍玄学,反正用数组模拟队列会MLE,必须动态分配内存。 #include<cstdio> #include<queue> using namespace std; #define ll long long ll const N=1e18+1; const int p[16]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; int k,b; queue<ll>q[16]; inline ll min(ll x,ll y){ return x<y?x:y; } inline void work1(){ for(register int i=1;i<=b;++i)q[i].push(p[i]); const int lt=k-1; int t(0); while(++t!=lt){ ll y=N; int x=0;