vis

武林 HDU - 1107

帅比萌擦擦* 提交于 2019-11-26 17:46:30
题目链接: https://vjudge.net/problem/HDU-1107 注意:题目中只有两个不同门派的人在同一个地方才能对决,其他情况都不能对决。 还有,这步的有效的攻击只有走到下一步之后才生效,所以会出现样例1和样例2的情况。 代码有注释,便于理解,这理我说一下vis[][][]数组的用处。 vis[x][x][1] 表示少林寺人的编号。 vis[x][x][2] 表示武当派人的编号。 vis[x][x][3] 表示峨眉派人的编号。 vis[x][x][4] 表示一个门派是否有超过两个人。 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <queue> 6 #include <map> 7 #include <cmath> 8 #include <iomanip> 9 using namespace std; 10 11 typedef long long LL; 12 #define inf (1LL << 25) 13 #define rep(i,j,k) for(int i = (j); i <= (k); i++) 14 #define rep__(i,j,k) for(int i = (j); i < (k); i

HDOJ 1026 Ignatius and the Princess I

血红的双手。 提交于 2019-11-26 17:41:11
经典BFS+记忆表 解题思路: 因为存在具有Hp为n的monster存在,如果直接压入队列,就有可能破坏广度优先树,因此必须在处理的过程中保证monster和‘.’的处理是保存同步的, 处理方法:如果当前位置是monster,那么我就削减他一个HP,再压入队尾,直到HP为0时,把地图上monster的位置置为‘.’可行位置,这样一来,monster 和‘.’的处理就同步了 路径记录:运用到算法导论上的记忆化BFS,具体的操作是建立一个记忆表 // 一次AC 0MS 444K 1 #include <queue> 2 #include <stdio.h> 3 #include <memory.h> 4 using namespace std; 5 6 const int maxn = 110 ; 7 char maze[maxn][maxn]; 8 int nNum, mNum, cnt, vis[maxn][maxn]; 9 int dx[] = {- 1 , 1 , 0 , 0 }; 10 int dy[] = { 0 , 0 , - 1 , 1 }; 11 12 struct node 13 { 14 int x, y, hp, step; 15 }; 16 17 struct parent 18 { 19 int px, py, pp; 20 }prev[maxn][maxn

ZOJ 1649 - Rescue BFS/优先队列

≯℡__Kan透↙ 提交于 2019-11-26 17:40:51
在HDOJ上提交通过以后,再在zoj上提交,结果得到了无数个WA,后来发现有一种情况我并没有考虑到 有几个关键的地方需要注意: 1. Angel的朋友不只有一个,可能有多个 2. guard的存在可能会破坏广度优先树 解决办法: BFS的做法:必须要保存guard与可行点‘.’的插入同步,因为guard的costTime不同,应该先不改变其坐标,costTime增加一以后,设为已被访问,‘x’变为‘.’或者‘#’,重新入队,此时,guard已被插入到队列的尾部,这样一来,guard与‘.’就可以同步了 View Code 1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include < string .h> 5 #include <memory.h> 6 7 char maze[ 210 ][ 210 ]; 8 int vis[ 210 ][ 210 ]; 9 int dx[] = {- 1 , 1 , 0 , 0 }; 10 int dy[] = { 0 , 0 , - 1 , 1 }; 11 int nNum, mNum, i, j, sx, sy; 12 13 struct Node 14 { 15 int x; 16 int y; 17 int step; 18 }; 19 20 int

Poj 1915 - Knight Moves 双向广搜

孤者浪人 提交于 2019-11-26 17:40:39
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int vis[ 305 ][ 305 ], mat[ 305 ][ 305 ]; 5 int dx[] = {- 2 , - 2 , - 1 , 1 , 2 , 2 , 1 , - 1 }; 6 int dy[] = {- 1 , 1 , 2 , 2 , 1 , - 1 , - 2 , - 2 }; 7 int casenum, nNum, sx, sy, tx, ty, i; 8 9 struct point 10 { 11 int x, y; 12 }cur, next, q[ 90005 ]={ 0 }; 13 14 int IsInBound( int x, int y) 15 { 16 return (x>= 0 && y>= 0 && x<nNum && y<nNum); 17 } /* IsInBound */ 18 19 int Solve() 20 { 21 int rear = - 1 ; 22 int front = - 1 ; 23 24 cur.x = sx; 25 cur.y = sy; 26 vis[sx][sy] = 1 ; /* 从起始位置开始的探索标记为 1 */ 27 q[++rear] = cur; /* 起始坐标入队 */ 28 29 next

Dijkstra

烈酒焚心 提交于 2019-11-26 17:40:00
Day 4 上午 赵和旭 概率 某个事件 A 发生的可能性的大小,称之为事件 A 的概率,记作 P(A) 。 假设某事的所有可能结果有 n 种,每种结果都是等概率,事件 A 涵盖其中的 m 种,那么 P(A)=m/n 。 例如投掷一枚骰子,点数小于 3 的概率为 2/6=1/3 。 如果两个事件 A 和 B 所涵盖的结果没有交集,那么 P(A 或 B 发生 )=P(A)+P(B) 还是掷骰子 P( 点数小于 3 或点数大于 4)=2/6+2/6=2/3 如果 A 和 B 所涵盖的结果有交集 那么 P(A 或 B 发生 )=P(A)+P(B)-P(A 与 B 同时发生 ) P( 点数小于 3 或点数为偶数 )=2/6+3/6-1/6=2/3 记事件 B 为“事件 A 不发生” 那么 P(A)+P(B)=1 ,即 P(B)=1-P(A) P( 点数不小于 3)=1-2/6=2/3 在两个互不干扰的事中,事件 A 在其中一件事中,事件 B 在另外一件事中 那么 P(A 与 B 同时发生 )=P(A)*P(B) 掷两个骰子, P( 第一个点数小于 3 且第二个点数为偶数 )=(2/6)*(3/6)=1/6 期望 事件 A 有多种结果,记其结果的大小为 x ,那么 x 的期望值表示事件 A 的结果的平均大小,记作 E(x) 。 E(x)= 每种结果的大小与其概率的乘积的和。 例如

网络流——最小费用最大流模板

混江龙づ霸主 提交于 2019-11-26 17:09:10
#zkw费用流# 参考网址: https://artofproblemsolving.com/community/c1368h1020435 zkw大佬的改进:①在dfs的时候可以实现多路增广②KM算法节省SPFA时间(然而我这里没有KM,要问为什么,当然是因为我不会了orz); but,参考了另外的博客,修修补补又三年~ 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <queue> 6 #include <cmath> 7 using namespace std; 8 const int maxv= 200010; 9 const int maxe= 2000010; 10 const int INF= 0x3f3f3f3f; 11 12 struct ENode 13 { 14 int to; 15 int c; 16 int f; 17 int Next; 18 }; 19 ENode edegs[maxe]; 20 int Head[maxv], tnt; 21 void init() 22 { 23 memset(Head, -1, sizeof(Head)); 24 tnt= -1; 25 } 26 void Add

HGOI20190809 省常中互测2

a 夏天 提交于 2019-11-26 17:05:08
   Problem A 时之终结 构造一个含有$n$个节点的无重边无自环的有向图, 使得从$1$出发,每一次经过一条$(u,v) (u < v)$的边到达节点$n$的方案恰好有$y$种。 对于$100\%$的数据,输出的无向图顶点树$n \leq 64 $给出的$y \leq 10^{18}$ Sol : 首先构造$63$个点的完全图,然后向第64个顶点连边,原问题等价于将$y$二进制拆分。    这样构造可以获得满分:复杂度$O( {log_2 n}^ 2)$ # include <bits/stdc++.h> # define int long long using namespace std; bool mp[65][65]; signed main() { int y; scanf("%lld",&y); int cnt=0; for (int i=1;i<=63;i++) for (int j=i+1;j<=63;j++) mp[i][j]=1,cnt++; for (int i=0;i<=63;i++) if ((y>>i)&1ll) mp[i+2][64]=1,cnt++; printf("64 %lld\n",cnt); for (int i=1;i<=64;i++) for (int j=i+1;j<=64;j++) if (mp[i][j]) printf("

POJ1475(Pushing Boxes)--bbffss

£可爱£侵袭症+ 提交于 2019-11-26 14:39:51
题目在这里 题目一看完就忙着回忆童年了。推箱子的游戏。 假设只有一个箱子。游戏在一个R行C列的由单位格子组成的区域中进行,每一步, 你可以移动到相邻的四个格子中的一个,前提是那个格子是空的;或者,如果你在箱子旁边,你也可以推动箱子前进一格,当然不能推到区域外面。 初始时你在其中某个格子内,你要把箱子推到指定格子。又由于箱子很重,所以你要用尽量少的推动次数。 Input 输入包含多组数据,每组数据第一行为两个正整数R和C,表示行数和列数。接下来R行,每行C个字符,描述游戏区域。用’#’表示石块,用’.’表示空的格子, 你的起始位置为’S’,箱子起始位置为’B’,箱子目标位置为’T’。 输入以R=C=0结束。 Output 对于第i组数据,如果不能将箱子推到指定格子,那么输出一行”Impossible.”(不含引号);否则,输出具有最少推动次数的操作序列。 如果有多个,则输出具有最少移动次数的操作序列。如果还有多个,输出任意一个即可。 操作序列是一行由’N’,’S’,’E’,’W’,’n’,’s’,’e’,w’组成的字符串,大写字母表示推动操作,小写字母表示移动操作,方向依次表示北,南,东,西。 这个题目轮玩的话可能都会玩,但是当初玩的时候可能不会去考虑用最少的步数去完成他,而是通过每一关就是完成任务了。 所以,就要重新审视这个题目了。 人要推着箱子将箱子推到目标处

Tarjan算法(lca)

隐身守侯 提交于 2019-11-26 14:31:04
http://codevs.cn/problem/2370 / 2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上。有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力。已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力 输入描述 Input Description 第一行一个n,接下来n-1行每一行有三个整数u,v, c 。表示节点 u 爬到节点 v 需要花费 c 的精力。第n+1行有一个整数m表示有m次询问。接下来m行每一行有两个整数 u ,v 表示两只虫子所在的节点 输出描述 Output Description 一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离。 样例输入 Sample Input 3 1 0 1 2 0 1 3 1 0 2 0 1 2 样例输出 Sample Output 1 1 2 数据范围及提示 Data Size & Hint 1<=n<=50000, 1<

线筛四连

放肆的年华 提交于 2019-11-26 14:27:24
线筛莫比乌斯函数 int prime[maxn],mu[maxn],cnt; bool vis[maxn]; void init(){ mu[1]=1; for(int i=2;i<maxn;i++){ if(!vis[i]){ prime[cnt++]=i; mu[i]=-1; } for(int j=0;j<cnt&&i*prime[j]<maxn;j++){ vis[i*prime[j]]=true; if(i%prime[j]) mu[i*prime[j]]=-mu[i]; else{ mu[i*prime[j]]=0; break; } } } } 线筛欧拉函数 int prime[maxn],phi[maxn],cnt; bool vis[maxn]; void init(){ phi[1]=1; for(int i=2;i<maxn;i++){ if(!vis[i]){ prime[cnt++]=i; phi[i]=i-1; } for(int j=0;j<cnt&&i*prime[j]<maxn;j++){ vis[i*prime[j]]=true; if(i%prime[j]==0){ phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*(prime[j]-1); } } }