vis

2017百度之星 资格赛

一曲冷凌霜 提交于 2020-02-15 15:02:34
1001 度度熊保护村庄 Accepts: 26 Submissions: 703 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 哗啦啦村袭击了喵哈哈村! 度度熊为了拯救喵哈哈村,带着自己的伙伴去救援喵哈哈村去了!度度熊与伙伴们很快的就过来占据了喵哈哈村的各个军事要地,牢牢的守住了喵哈哈村。 但是度度熊发现,这是一场旷日持久的战斗,所以度度熊决定要以逸待劳,保存尽量多的体力,去迎战哗啦啦村的战士。 于是度度熊决定派尽量多的人去休息,但是同时也不能松懈对喵哈哈村的保护。 换句话而言,度度熊希望尽量多的人休息,而且存在一个包围圈由剩下的人组成,且能够恰好的包围住喵哈哈村的所有住房(包括边界)。 请问最多能让多少个人休息呢? Input 本题包含若干组测试数据。 第一行一个整数n,表示喵哈哈村的住房数量。 接下来n行,每行两个整数(x1[i],y1[i]),表示喵哈哈村的住房坐标。 第n+1行一个整数m,表示度度熊的士兵数量。 接下来m行,每行两个整数(x2[i],y2[i]),表示度度熊伙伴的坐标。 满足: 1<=n,m<=500 -10000<=x1[i],x2[i],y1[i],y2[i]<=10000 Output

[Updating]点分治学习笔记

拜拜、爱过 提交于 2020-02-14 18:18:10
[Updating]点分治学习笔记 Upd \(2020/2/14\) ,补了一道例题LuoguP3085 [USACO13OPEN]阴和阳Yin and Yang To Do List 待填 LuoguP2664 树上游戏 动态点分治。 这个看心情写吧......是贞德不想写qwq 嘛...上个世纪学的...好像全忘了....来写一下吧 这个应该算树上路径类问题的一类trick吧... che dan环节 点分治嘛,顾名思义,先抓树上一个点算它对答案贡献,然后把这个点割掉,会变成几棵小一点的树,然后递归算就好了。 那么问题来了,点要怎么选呢? rand一个 如果说他是一条链的话从上往下选点就被卡 \(n^2\) 了 默默码起手中的暴力 ,随便rand又有被针对的风险... 在分治递归的时候,每一层递归的总复杂度我们不想管它,我们要控制的就是每一次选点使得递归的层数变少。 树上有一个名词叫做 重心 详见CSP-2019 D2T3 ,重心旁边的子树大小最大是不会超过 \(n/2\) 的,所以我们每次点分治的时候先找当前分治到的这一联通块内的重心,然后算重心对答案的贡献在把重心割掉,分治就好了。 这样做递归的层数是不会超过 \(\log n\) 的,具体的算一点对答案的贡献针对题目来看。 那怎么找重心呢?重心的定义,对于一棵树,其重心的最大子树大小一定是最小的,所以对树 \(Dfs\)

C#设计模式——访问者模式(Visitor Pattern)

元气小坏坏 提交于 2020-02-14 12:34:16
一、概述 由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改。对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能。 二、访问者模式 访问者模式表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。其结构图如下: Visitor为每一个ConcreteElement声明一个Visitor操作。 ConcreteVisitor实现了Visitor声明的操作,其定义的行为就是需要动态添加到ConcreteElement中的新功能。 Element定义一个以Visitor为参数的Accept操作。 ConcreteElement实现Accept操作。 ObjectStructure能枚举它的元素,可以提供一个高层接口以允许访问者访问它的元素。 访问者模式通过双重分派(double dispatch)的方法来透明的为各个类添加新的功能,第一重分派是指Accept方法的多态,第二重分派是指Visit方法的多态。 访问者模式的主要缺点在于增添新的Element子类的时候会导致Visitor类发生改变,而且随着Element子类的增加,Visitor类会越来越庞大。 三、示例 我们看一下访问者模式的简单应用。 首先定义一个公司的员工管理系统的基本员工类

Codeforces Round #516 (Div. 2)D. Labyrinth(BFS)

生来就可爱ヽ(ⅴ<●) 提交于 2020-02-14 00:25:36
题目链接: http://codeforces.com/contest/1064/problem/D 题目大意:给你一个n*m的图,图中包含两种符号,'.'表示可以行走,'*'表示障碍物不能行走,规定最多只能向左走L个格子,向右R个格子,但是上下没有限制,现在给出出发点坐标(sx,sy),求能走的最大单元格数目。 Examples Input Copy 4 53 21 2......***....***.... Output Copy 10 Input Copy 4 42 20 1......*......... Output Copy 7 解题思路:直接用BFS模拟行走过程,不过需要多记录下向左和向右行走的步数。为了保证保留向左向右行走的次数,我们优先向上下行走,能向上下行走就先不往左右行走。直接用双向队列,如果是向上下行走就放在队首,如果是左右行走放在队尾。 附上代码: #include<bits/stdc++.h> using namespace std; int n,m,vis[2005][2005],ans,sx,sy,L,R; int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}}; char mp[2005][2005]; struct node{ int x,y,l,r; }; bool check(node x) { if(x.x<=0

POJ 3414 Pot (输出路径)【BFS】

混江龙づ霸主 提交于 2020-02-13 14:20:04
< 题目 链接 > 题目大意: 有两个容量的空杯子,能够对这两个空杯子进行三种操作: 分别是fill(a),装满a杯子; drop(a),倒空a杯子; pour(a,b),将a杯子中的水倒入b杯子中; 现在问你,是否能够通过这三种操作,使得这两个杯子中至少有一个杯子中含有c体积的水,如果不行,输出“impossible”,如果可以,输出操作的步数,以及每一步的具体操作。 解题分析: 此题与一道输出路径的很相像,只不过那道题是输出每一次操作对应的点的状态,而此题是要输出具体的操作。不难想到,我们依然可以记录下BFS路径上点的状态,然后根据这个点和上一个点的状态差距推导出它们之间的具体操作。 #include <cstdio> #include <cstring> int v[5],m; const int maxn=100000; int vis[110][110]; int flag; struct node{ int val[5]; int step; int pre; //记录上一个点在que[]数组中的位置 node(int a=0,int b=0,int c=0,int d=-1){ val[1]=a,val[2]=b,step=c,pre=d; } }que[maxn]; void fill(node &now,int a){ now.val[a]=v[a]; }

算法竞赛模板 最小生成树

ε祈祈猫儿з 提交于 2020-02-13 14:08:09
①克鲁斯卡尔算法(Kruskal) n 是顶点数, m 是边数; cnt 是已连的边数,如果已连的边数=总点数-1,即可跳出。 #include<bits/stdc++.h> #define MAX 1005 using namespace std; int p[MAX],n,m; struct edge{ int x,y,w; }a[MAX]; int find(int r) { if(p[r]!=r) p[r]=find(p[r]); return p[r]; } void join(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) p[fx]=fy; } void init() { for(int i=0;i<=MAX;i++) p[i]=i; } bool cmp(edge a,edge b) { return a.w<b.w; } int kruskal() { sort(a,a+m,cmp); int cnt=0,cost=0,i; for(i=0;i<m;i++) { int fx=find(a[i].x),fy=find(a[i].y); if(fx!=fy) { p[fx]=fy; cost+=a[i].w; cnt++; } if(cnt==n-1)break; } return cost; } int

最小生成树(模板)

匆匆过客 提交于 2020-02-13 14:07:16
51nod1212最小生成树模板题: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1212 克鲁斯卡尔(加边法):先取最小的边,在判断是不是一个集合(不是舍去,是加上) 普里姆(加点法):先已经判断了不是一个集合,再从不是的集合中找出最小的边把点加入,最后更新(再取,再更新。。) 都是加到n-1条边停止(n个点最少由n-1条边连通),另外,Kruskal不用考虑重边(并查集自动取舍),Prim需要考虑重边(不考虑必错!) (关于去最小边,克鲁斯卡尔事先排序好按顺序取即可,所以是n*logn;普里姆每轮之后都要更新,所以每次取都循环找一次,所以是n*n,当然最后还可以优化这里就不说了) 克鲁斯卡尔 以边为重点进行各种操作,点不是重点,所以存图方式不重要很简单。(把边连接信息表示出来就行,结构体完美表示) 另外关于并查集,初学并查集推荐不用深度优化,只改变父节点就行更加好理解,而且时间也差不了多少 初级并查集 1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <iomanip> 5 #include <cstdio> 6 #include <cstring> 7 using namespace std; 8

素数判定的三种方法(cpp代码)

假如想象 提交于 2020-02-13 12:15:23
文章目录 一般方法 埃拉托斯特尼筛法(埃氏筛) 线性筛 一般方法 原理概述: 1不是质数也不是合数,特殊处理; 从2枚举到 √x,若有能除尽的数直接返回x不是素数 Q:为什么枚举到√x? 若m整除n(其中n>根号m)则m=n*k。 若m不整除从1除到√m的数它就不可能整除根号m后面的数。 如果根号m有小于√m的因子X,那么N必定有大于√m的因子Y与X对应。 而且X *Y=m (来源:百度) 实现说明: 略 bool isPrime_usual ( int x ) { if ( x == 1 ) return false ; for ( int i = 2 ; i * i <= x ; i ++ ) if ( x % i == 0 ) return false ; return true ; } 埃拉托斯特尼筛法(埃氏筛) 原理概述: 从最小的素数2开始,2…3…5…将这些数的倍数标为合数。 实现说明: 首先要有一个数组vis,用来标记那些数是素数,所得结果也存在这个数组,并都初始化为true(即默认所有数都是素数) 从2开始枚举,若vis[i]==true,则用一个循环去将vis[i]的倍数都标记为非素数。个人感受j从i * i开始好一些,有一些从j=2*i开始会降低效率(重复筛)。 bool vis [ Maxn ] ; void isPrinme_era ( ) {

Leetcode 1345:跳跃游戏IV(超详细的解法!!!)

丶灬走出姿态 提交于 2020-02-13 11:16:45
给你一个整数数组 arr ,你一开始在数组的第一个元素处(下标为 0)。 每一步,你可以从下标 i 跳到下标: i + 1 满足: i + 1 < arr.length i - 1 满足: i - 1 >= 0 j 满足: arr[i] == arr[j] 且 i != j 请你返回到达数组最后一个元素的下标处所需的 最少操作次数 。 注意:任何时候你都不能跳到数组外面。 示例 1: 输入:arr = [100,-23,-23,404,100,23,23,23,3,404] 输出:3 解释:那你需要跳跃 3 次,下标依次为 0 --> 4 --> 3 --> 9 。下标 9 为数组的最后一个元素的下标。 示例 2: 输入:arr = [7] 输出:0 解释:一开始就在最后一个元素处,所以你不需要跳跃。 示例 3: 输入:arr = [7,6,9,6,9,6,9,7] 输出:1 解释:你可以直接从下标 0 处跳到下标 7 处,也就是数组的最后一个元素处。 示例 4: 输入:arr = [6,1,9] 输出:2 示例 5: 输入:arr = [11,22,7,7,7,7,7,7,7,22,13] 输出:3 提示: 1 <= arr.length <= 5 * 10^4 -10^8 <= arr[i] <= 10^8 解题思路 最少操作次数问题,那么可以考虑通过 bfs 来处理

LCA最近公共祖先模板代码

China☆狼群 提交于 2020-02-13 06:21:04
vector模拟邻接表: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<vector> 6 #include<queue> 7 #define eps 1e-8 8 #define memset(a,v) memset(a,v,sizeof(a)) 9 using namespace std; 10 typedef long long int LL; 11 const int MAXL(1e4); 12 const int INF(0x7f7f7f7f); 13 const int mod(1e9+7); 14 int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}}; 15 int father[MAXL+50]; 16 bool is_root[MAXL+50]; 17 bool vis[MAXL+50]; 18 vector<int>v[MAXL+50]; 19 int root; 20 int cx,cy; 21 int ans; 22 int Find(int x) 23 { 24 if(x!=father[x]) 25 father[x]=Find(father[x]); 26 return father[x];