vis

Codeforces Round #578 (Div. 2)

不羁岁月 提交于 2019-11-27 04:08:11
A. Hotelier(水题) 题意:有0-9号,10个房间,客人可以从左边进,右边进,L代表从左边进,R代表从右边进,0-9代表该房间的客人离开,从左右进的都选择住离入口最近的,然后 问在操作结束后每个房间是否还有人。 题解:遍历一遍就行了~ #include <bits/stdc++.h> using namespace std; const int maxn=1e5+10; typedef long long ll; bool vis[maxn]; int main(){ int n; cin>>n; string s; cin>>s; int l=0,r=9; memset(vis,0,sizeof(vis)); for(int i=0;i<s.size();i++){ if(s[i]=='L'){ for(int j=0;j<=9;j++){ if(!vis[j]){ vis[j]=true; break; } } } else if(s[i]=='R'){ for(int j=9;j>=0;j--){ if(!vis[j]){ vis[j]=true; break; } } } else vis[s[i]-'0']=false; } for(int i=0;i<=9;i++){ if(vis[i])cout<<1; else cout<<0; } cout<<endl;

练习09-三种匹配算法(模板)

做~自己de王妃 提交于 2019-11-27 04:04:27
一、 匈牙利算法 解决二分图中的最大匹配问题(很多时候都可以把题目转变成二分图, 刚学网络流有点头大 )。两个互不相交的子集V1 ,V2 寻找他们能匹配到的最大数量。(由于我菜鸡,仅仅给出几种模板,网上有很多博客讲的很好了) 1、邻接表实现(O( n^3) 模板秒切 过山车 【模板】二分图匹配 [ZJOI2009]假期的宿舍 #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=1001; int n1,n2,k; //n1,n2为二分图的顶点集,其中x∈n1,y∈n2 int map[N][N],vis[N],link[N]; //link记录n2中的点y在n1中所匹配的x点的编号 int find(int x) { int i; for(i=1;i<=n2;i++) { if(map[x][i]&&!vis[i])//x->i有边,且节点i未被搜索 { vis[i]=1;//标记节点已被搜索 //如果i不属于前一个匹配M或被i匹配到的节点可以寻找到增广路 if(link[i]==0||find(link[i])) { link[i]=x;//更新 return 1;//匹配成功 } } } return 0; } int main() { int i,x

广搜优化题目总结

被刻印的时光 ゝ 提交于 2019-11-27 03:56:44
广搜优化题目总结 电路维修* 这道题之前打过,但那时候打题太水了,没有真正掌握这道题的知识点。( 果然我还是太蒻了 ) 这道题的解法是先建边,对于每一个单位正方形,将有边相连的两个对角建一条长度为0的无向边,另外两个对角建一条长度为1的无向边。然后可以跑最短路或者用 双端队列bfs ( 0-1bfs )。 跑最短路的话要注意由于是网格图spfa会炸掉,所以要用堆优化的dijkstra( ~~不会不加堆优化的dijkstra (^_^)~~ ) 因为在练习广搜,所以我用的是双端队列bfs 当我们遇到边权只有1的情况时,显然直接bfs,然后第一次访问到某个点的“时间”就是到它的最短路径 当边权同时存在1和0两种情况时,我们就可以采用双端队列bfs,也叫作0-1bfs,就是访问时,若边权为0,则把目标点v放在队首,若边权为1,则把目标点放在队尾,这样是为了使得边权为0时的目标点v先被访问。 我按照这个思路做了,但却WA了,后来我一看题解,队列里维护的居然不是点,而是边,我一直想不通为什么,找了半天也只有题解模糊地写到,然后我就自己手玩了一把,发现如果是维护点,那么有可能会出现这样的情况:显然如果边权为0,那么目标点v与点u应该处于广搜的同一层,但如果是维护点,就可能会出现点v在被点u访问到之前被下一层的点提前访问了(也就是由这一层的点通过边权为1的边得到的目标点vv访问过来

hdu1016 质数环

只愿长相守 提交于 2019-11-27 02:44:43
题目链接: Prime Ring Problem 给定一个环和1~n,让你将其填到环上,使其相邻的数相加为质数。 思路:首先题目要求找出所有的情况并打印,dfs可以进行处理。考虑数组代替环存,最后放完n个数的时候加一个首尾和判断。使用dfs进行试探,如果满足条件继续深搜,不满足则回退。 dfs函数: void dfs(int x) //参数的含义是填了多少个数 { a[0]=1; if(x==n&&isprime(a[0]+a[n-1])) //满足条件直接输出 { for(int i=0;i<n-1;i++) { cout<<a[i]<<" "; } cout<<a[n-1]<<endl; } else { for(int i=2;i<=n;i++) //由于首部为1,所以从2开始进行搜索,这个循环保证所有数都能用到 { if(isprime(a[x-1]+i)&&vis[i]==0) //vis表示该数字是否被用过【因为每个数字只能用一次】 { vis[i]=1; a[x]=i; dfs(x+1); //下一步搜索 vis[i]=0; } } } } 完整代码: #include<bits/stdc++.h> using namespace std; int a[105],vis[105],n; bool isprime(int x) { for(int i=2;i*i<=x

ida* 的一些题 ida*小结

╄→尐↘猪︶ㄣ 提交于 2019-11-27 01:39:34
这些题都是 http://www.cnblogs.com/ambition/archive/2011/07/25/search_plus.html   里的。。我的一些代码也参考了里边的代码 HDU 1043 Eight 话说是一道涉及到人生完整不完整的题 八数码 判断有没有解:求出所给状态的逆序数m,如果同是奇数则无解,偶数则有解。  why? 因为移动一次逆序数 加2 或 减2 (我也不会证,就是自己试了下,发现是)    在我的程序中空位用0表示    方法一: A*    估价函数: 计算当前状态到目标状态的 曼哈顿距离。 因为移动一次,曼哈顿距离 加1或减1,所以直接返回曼哈顿距离    状态存储: 采用 康托 法。 把一个图转化成一个数。   判重:   把图转化为 康托数后,用个 hash 9!=362880    然后就是bfs了。    用一个pre 数组记录路径 A* 是要用优先队列了,无奈于对堆不太熟练,于是用了STL 下面对程序的执行过程简略介绍:    对于每个结点存 了当前的图G(用了康托后就是一个数, (可以不用康托数,直接开个数组 记录整个图)我的第二个程序就是这样的。 当前已走多少步step, 当前状态到目标状态的曼哈顿距离dis, 则预计至少h步到目标状态(h=step+dis) 优先队列就是根据 按上从小到大排序的      (STL

最短路径

痴心易碎 提交于 2019-11-27 00:27:50
没有用的话qaq : Ummmm…图论的大部分知识本来早就有学过,只是一直没有写成博文来梳理,但既然上了qbxt DP图论就写一篇来总结下, 主要是来听DP的,但…由于太菜的原因,DP听得天花乱坠QWQ 图中的最短路算法分为单源最短路算法(dijkstra,Bellman-food,spfa)和多源最短路算法(floyd),单源最短路算法是求图上一点到其他任意一点的最短路径,多源最短路算法是求图上任意两点之间的最短路。 一,多源最短路算法 Floyd弗洛伊德算法,运用了动态规划的思想,用邻接矩阵存储,期初将从任何一点到其他所有点的最短路都置成正无穷,然后输入时修改有的权值,其主要思想是动态规划,在最外围枚举点,看看有没有一个点可以更新两点之间的最短路。 代码简单易懂 memset(dis,0x3f,sizeof(dis)); for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); 时间复杂度为O(n^3 ),空间复杂度为O(n^2),时间和空间均不是很优,一般较少采用,一般在求n范围较小的多源最短路题中才有出现。 可以适用于有负权边的情况,可以判断图的连通性,可以传递闭包 二,多源最短路算法 1,Dijkstra a

Luogu P1462 && P1951

江枫思渺然 提交于 2019-11-27 00:12:47
首先有两个最短路,可以考虑把一个东西拿出来二分,也就是可以二分最小值,但是注意不要用SPFA 他死了 ,可以用Dij跑最短路,再二分,效率会大大提高 1.SPFA #include<bits/stdc++.h> using namespace std; const int N=1e4+5; const int M=1e5+5; int n,m,tot,head[M]; long long f[N],d[N],b,a[N]; bool vis[N]; struct node{int to,next;long long val;}e[M]; void add(int u,int v,int w){e[++tot].to=v;e[tot].next=head[u];e[tot].val=w;head[u]=tot;} bool spfa(long long k){ queue<int> q; if(a[1]>k||a[n]>k)return false; memset(vis,0,sizeof(vis)); for(int i=2;i<=n;i++)d[i]=LLONG_MAX; d[1]=0;q.push(1);vis[1]=1; while(!q.empty()){ int u=q.front();q.pop();vis[u]=0; for(int i=head[u];i;i=e[i

130. 被围绕的区域(Surrounded Regions)

亡梦爱人 提交于 2019-11-26 21:26:02
Leetcode之深度优先搜索(DFS)专题-200. 岛屿数量(Number of Islands) 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。 示例 1: 输入: 11110 11010 11000 00000 输出: 1 示例 2: 输入: 11000 11000 00100 00011 输出: 3 分析:这题同样是求连通块,相比于 130. 被围绕的区域(Surrounded Regions) 题少了很多限制条件,同样引入vis,点从其四个方向搜索。 class Solution { int vis[][] = null; int dirx[] = {0,0,1,-1}; int diry[] = {1,-1,0,0}; public int numIslands(char[][] grid) { if(grid==null || grid.length==0){ return 0; } int ans = 0; vis = new int[grid.length][grid[0].length]; for(int i=0;i<grid.length;i++){ for(int j=0;j<grid[0].length;j++){ if

【hash表】门票

╄→尐↘猪︶ㄣ 提交于 2019-11-26 21:09:02
问题 I: 【哈希和哈希表】门票 题目描述 RPK要带MSH去一个更加神秘的地方! RPK带着MSH穿过广场,在第1618块砖上按下了一个按钮,在一面墙上随即出现了一个把手。RPK握住把手,打开了一扇石质大门。他们穿过悠长而芬芳的小道,走到了一扇象征时间的大门――“the gate of time”。 门上写着一个关于时间的谜题“承诺:____年”,RPK思考了一会,从容地用手指写下1万,这时,门开始发出闪光,MSH感觉到自己的心跳都快停止了。 门开了,眼前是一座美丽的神秘花园! 正当RPK和MSH准备进入的时候,突然出现了一个看门的老大爷QL。 QL:“你们干什么你们,还没买票呢!” RPK突然想起来现金全拿去买蛋糕了,RPK很绅士的问:“能刷卡么?我身上没现金。” QL:“没钱?那你们不能进去!” RPK(汗):“……” QL:“等等,我这有道不会的数学题,你解了我就让你们进去。” (众人:“……”) 有一个数列{an},a0=1,ai+1=(A*ai+ai mod B)mod C,要求这个数列第一次出现重复的项的标号。 这点小问题当然难不倒数学bug男RPK了,仅凭心算他就得到了结果。 输入 一行3个数,分别表示A B C 输出 输出第一次出现重复项的位置,如果答案超过2000000 输出-1 样例输入 2 2 9 样例输出 4 提示 30%的数据A B C≤1e5 100

NOIP2011 复盘(有锅)

我的梦境 提交于 2019-11-26 21:07:31
NOIP2011 复盘 D1T1 P1003 铺地毯 经典题目,不必多说 #include<bits/stdc++.h> using std::cin; using std::cout; using std::endl; const int maxn = 10005; int a[maxn], b[maxn], g[maxn], k[maxn], n; int x, y; int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d %d %d %d", &a[i], &b[i], &g[i], &k[i]); scanf("%d %d", &x, &y); for(int i = n; i >= 1; i--) { if(a[i] <= x && x <= a[i] + g[i] && b[i] <= y && y <= b[i] + k[i]) { printf("%d\n", i); return 0; } } printf("-1\n"); return 0; } D1T2 P1311 选择客栈 对于最低消费,套一个ST表求RMQ。 我们将相同的色调的点一起存,然后考虑用暴力跑出答案。 然后可以发现,如果左端点固定,只需要按顺序向右找第一个满足条件的点,后面的点来组成一定都可以。