vis

Round #623(div2)

拥有回忆 提交于 2020-03-16 17:50:15
A. Dead Pixel 网速题(不过我又是补题) for _ in range(int(input())): x,y,n,m = map(int,input().split()) n += 1 m += 1 print(max(x*(m-1),x*(y-m),y*(n-1),y*(x-n))) B. Homecoming 题意: 给一个只包含 A 和 B 的字符串,代表两种站,你可以从位置 \(i\) 到达位置 \(j\) 如果 \(i,i+1,...,j-1\) 都是同一种站,并花费相应的金钱(如果全是A站则花费a元,否则 b 元)。 现给出 \(a,b,p\) 代表了两种站的花费和你目前的余额 再给出串 \(s\) , 问你最小要从哪个站台开始,才能用你的钱到达终点 这道题一开始在疯狂模拟,细节处理的不是很好,还写错了,心态崩了,先放了一放。 直到我看到 \(tag\) 有一个二分 我为什么老是想不到二分答案 def judge(idx,a,b,p,s): i = idx - 1 n = len(s) cost = 0 while i < n: if s[i] == 'A': cost += a else: cost += b while i + 1 < n and s[i] == s[i+1]: i += 1 return True if cost <= p else

spfa的魔改方法

北慕城南 提交于 2020-03-11 07:40:21
spfa的魔改方法 ( \(update\) \(on\) \(2019/8/13\) ) 参考文献: spfa的玄学优化和Hack方法 学图论,你真的了解最短路吗? ETO组织成员 的题解小合集系列 题外话: 关于这篇博客的题目,我想了几个(光速逃……: 关于BellmanFord转生变成spfa的那些事 欢迎来到效率至上主义的OI图论 RE:从零开始的图论生活 能跑网格图,还能卡过菊花图,这样的spfa你喜欢吗 某科学的队优spfa 我的无优化spfa果然有问题 进入正题: 先来说一下 \(spfa\) 吧, \(spfa\) 的全称是 \(Shortest\) \(Path\) \(Fastest\) \(Algorithm\) ,其实就是 \(Bellman\) - \(Ford\) 算法加上一个队列优化。 其时间复杂度并不稳定,最快可以达到 \(O(1)\) ,最慢会被卡成 \(Bellman\) - \(Ford\) 的 \(O(nm)\) 今天就来总结一下学到的 \(spfa\) 的各种魔改: 前置:读入优化 由于毒瘤出题人很有可能会卡时间,所以我们需要读优(输出优化不一定) 标准代码:(随用随复制) inline int read() { int fu=1,x=0;char o=getchar(); while(o<'0'||o>'9'){if(o=='-')fu=

dfs需要剪枝

我们两清 提交于 2020-03-10 05:23:42
问题 G: 优美的排列 题目描述 假设有从 1 到 N 的 N 个整数,如果从这 N 个数字中成功构造出一个数组,使得数组的第 i 位 (1 <= i <= N) 满足如下两个条件中的一个,我们就称这个数组为一个优美的排列。条件: I. 第 i 位的数字能被 i 整除 II. i 能被第 i 位上的数字整除 现在输入一个整数 N,请问可以构造多少个优美的排列? 输入 输入样例由多组测试数据组成。每组测试数据第一行输入一个正整数 N ( 1 <= N <= 15 ) 输出 输出可以构造的优美的排列的数量 样例输入 2 样例输出 2 提示 参照输入样例: 第 1 个优美的排列是 [1, 2]: 第 1 个位置(i=1)上的数字是1,1能被 i(i=1)整除 第 2 个位置(i=2)上的数字是2,2能被 i(i=2)整除 第 2 个优美的排列是 [2, 1]: 第 1 个位置(i=1)上的数字是2,2能被 i(i=1)整除 第 2 个位置(i=2)上的数字是1,i(i=2)能被 1 整除 AC代码: # include <bits/stdc++.h> using namespace std ; int n , ans , k ; int a [ 25 ] ; bool vis [ 25 ] ; void dfs ( int m ) { for ( int i = 1 ; i <= n ;

DFS

孤人 提交于 2020-03-09 09:53:35
LC46. Permutations 给一个包含不重复元素的集合,返回其所有排列 分析:用dfs,用一个数组vis记录某个元素是否已经被使用,使用的时候 vis[i] = 1 ,回溯的时候 vis[i] = 0 ,用 idx 记录当前排列要放数据的位置 class Solution { public: vector<int> nu, vis, cur; vector<vector<int>> res; int n; void dfs(int idx) { if (idx == n) { res.push_back(cur); return; } for (int i = 0; i < n; ++i) { if (vis[i]) continue; vis[i] = 1; cur[idx] = nu[i]; dfs(idx + 1); vis[i] = 0; } } vector<vector<int>> permute(vector<int>& nums) { n = nums.size(); if (!n) return res; nu = nums; vis.assign(n, 0); cur.assign(n, 0); dfs(0); return res; } }; View Code 来源: https://www.cnblogs.com/betaa/p/12446910

分层最短路

雨燕双飞 提交于 2020-03-08 16:52:00
分层最短路的理解 模板 洛谷P4568 题解 hdu3499 题解 用一张图解释 就是把free的路线进行分层计算到这个点的距离最小是多少,假设点为pos mindis=min(mindis,dis[pos+i*n]);0<=i<=free n是多少个点 洛谷P4568 题意: 在一个带权无向图,n个点,m条边,k个权力(使得一条边权变成0) 再给起始位和终点位,给m条边的u,v,w的信息,求最少路费 思路: m小于等于50000,k小于等于10,链式前向星的话需要2*2*(10+1)(双向*建零边和带权边(k+1层)) 因为当i==k的时候,权力是0,所以不用建第k层的零边的 用dijkstra跑就行了 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define il inline 5 #define it register int 6 #define inf 0x3f3f3f3f 7 #define lowbit(x) (x)&(-x) 8 #define pii pair<int,int> 9 #define mak(n,m) make_pair(n,m) 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 #define mod

Uncle Tom's Inherited Land*

馋奶兔 提交于 2020-03-06 16:54:00
最大匹配问题 题意:题目意思: 给定一个 n * m 的矩阵格子, 第二行给定一个k值表示池塘,接下来给出池塘坐标,要求的就是在不是池塘的区域用1 * 2 的小矩形填充它 ,问 最多能填充几个小矩形,并且打印出所有矩阵! 这题拿到手毫无头绪 是这个专题最难的一题了 这题值得多打几遍 #include<bits/stdc++.h> using namespace std; #define N 105 int mp[N][N]; int used[N]; int vis[N]; int n,m,r,c; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; int flag[N][N]; int ans[N][2]; int cnt; vector<int>g[N*N]; bool dfs(int x) { for(int j=0;j<g[x].size();j++) { if(!used[ g[x][j] ]) //所有的j都改为了g[x][j] { used[ g[x][j] ]=1; if(!vis[ g[x][j] ]||dfs(vis[ g[x][j] ])) { vis[ g[x][j] ]=x; return true; } } } return false; } int find1(void) { int ans=0; memset

Noip2017 棋盘——普及组

╄→гoц情女王★ 提交于 2020-03-06 09:50:58
原题地址(点我) 题目描述 有一个m × m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。 任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上、 下、左、 右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费 1 个金币。 另外, 你可以花费 2 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用, 而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法; 只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。 现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少? 输入输出格式 输入格式: 数据的第一行包含两个正整数 m, n,以一个空格分开,分别代表棋盘的大小,棋盘上有颜色的格子的数量。 接下来的 n 行,每行三个正整数 x, y, c, 分别表示坐标为( x, y)的格子有颜色 c。 其中 c=1 代表黄色, c=0 代表红色。 相邻两个数之间用一个空格隔开。 棋盘左上角的坐标为( 1, 1),右下角的坐标为( m, m)。

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)

纵然是瞬间 提交于 2020-03-06 00:01:29
地址: http://codeforces.com/contest/1305         题意 : A题写这么长,实际上意思很简单,给出两组长度相等的数,让你给出排列顺序,保证每一列上下加起来不同。     解析:很水了,小+大=大+小,根据这个,只要上下均按从小到大的顺序排列就可以了。 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<algorithm> using namespace std; typedef long long ll; int a[1005],b[1005]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; for(int i=0;i<n;i++) cin>>b[i]; sort(a,a+n);sort(b,b+n); for(int i=0;i<n-1;i++) cout<<a[i]<<" "; cout<<a[n-1]<<endl; for(int i=0;i<n-1;i++) cout<<b[i]<<" "; cout<<b[n-1]<<endl; } }      题意:题意我是理解了有一会儿

CodeCraft-20 (div 2) 做题记录

女生的网名这么多〃 提交于 2020-03-05 18:50:42
A. 把所有都放到1号上就行了 1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 int T,n,m; 5 int main() 6 { 7 scanf("%d",&T); 8 while(T--) 9 { 10 scanf("%d%d",&n,&m); 11 int s=0; 12 for(int x,i=1;i<=n;++i)scanf("%d",&x),s+=x; 13 printf("%d\n",min(m,s)); 14 } 15 } View Code B. 找规律,长度为k的翻转是从k开始的一个后缀拼上剩下的前缀 这个前缀可能是正着的可能是反着的,发现和n,k的奇偶性有关 1 #include<bits/stdc++.h> 2 #define maxn 5005 3 using namespace std; 4 int T,n; 5 char str[maxn]; 6 pair<string,int> s[maxn]; 7 int main() 8 { 9 scanf("%d",&T); 10 while(T--) 11 { 12 memset(str,0,sizeof(str)); 13 scanf("%d",&n); 14 scanf("%s",str+1); 15

DFS入门

自作多情 提交于 2020-03-05 10:59:14
题目描述 排列与组合是常用的数学方法。 先给一个正整数 ( 1 < = n < = 10 ) 。例如n=3,所有组合,并且按字典序输出: 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 输入 输入一个整数n( 1<=n<=10) 输出 输出所有全排列 每个全排列一行,相邻两个数用空格隔开(最后一个数后面没有空格) 代码 global n num=[] vis=[] def DFS(x): if x==n: for i in range(n-1): print(str(num[i]),end=' ') print(num[n-1]) return for i in range(n): if vis[i]==0: vis[i]=1 num[x]=i+1 DFS(x+1) vis[i]=0 if __name__=="__main__": n=int(input()) vis=[0]*n num=[0]*n DFS(0) 题目描述 排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r < = n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。 现要求你不用递归的方法输出所有组合。 例如n = 5 ,r = 3 ,所有组合为: 1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3