vis

蓝桥杯 搜索

倾然丶 夕夏残阳落幕 提交于 2019-12-27 07:59:45
完美正方形 如果一些边长互不相同的正方形,可以恰好拼出一个更大的正方形,则称其为完美正方形。 历史上,人们花了很久才找到了若干完美正方形。比如:如下边长的22个正方形 2 3 4 6 7 8 12 13 14 15 16 17 18 21 22 23 24 26 27 28 50 60 如【图1.png】那样组合,就是一种解法。此时, 紧贴上边沿的是:60 50 紧贴下边沿的是:26 28 17 21 18 22阶完美正方形一共有8种。下面的组合是另一种: 2 5 9 11 16 17 19 21 22 24 26 30 31 33 35 36 41 46 47 50 52 61 如果告诉你该方案紧贴着上边沿的是从左到右依次为:47 46 61, 你能计算出紧贴着下边沿的是哪几个正方形吗?        解题思路:       三个关键          当前位置能否填入          填入是否符合要求          填入结束条件 1 #include<iostream> 2 #include<cstring> 3 4 using namespace std; 5 6 7 const int maxn=154; 8 int Num[]={2,5,9,11,16,17,19,21,22,24,26,30,31,33,35,36,41,50,52}; 9 int mp[maxn

动态点分治学习笔记

筅森魡賤 提交于 2019-12-27 07:09:44
学习动态点分治之前要先弄清楚点分治的原理,二者的应用范围的不同就在于动态的支持在线修改操作,而实现的不同就在于动态点分治要建点分树。 OI中有很多树上统计问题,这类问题往往都有一个比较容易实现的暴力做法,而用高级数据结构维护信息有显得过于复杂,有没有一种“优美的暴力”,能既保证思维的简单性,又有更高效的时间复杂度保证呢?这就是点分治的思想。 点分治的实现过程是:每次找到当前树的重心,然后以这个重心为根统计这个树的信息,然后对重心的每个孩子分别递归,同样用将重心作为根的方法统计子树的信息(这里可能要除去不合法的重复影响)。为什么复杂度有保证呢?我们先来看重心的性质。 以一棵树的重心作为根,则根的最大子树的size不超过整个树size的一半。考虑证明,因为重心的定义是使以它作为根的树的最大子树size最小,那么如果重心某一个子树size超过整个树的一半,则一定能找到另一个节点使这个节点作为根树的最大子树size比重心更小,矛盾。 那么我们可以得到,每个重心都有自己的管辖范围(事实上因为是分治,所以所有点都是某一块(或仅仅是它自己)的重心),而管辖一个点的重心最多有$O(\log n)$个。所以如果每个点被管辖自己的重心处理一次,那么总次数是$O(n \log n)$个的。 基于这个思想,我们得到了点分治的实现方法。 关于如何找重心,直接DP即可,注意传入S为这棵树的size,以及f

POJ3294:Life Forms——后缀数组

我只是一个虾纸丫 提交于 2019-12-27 04:28:53
题面    POJ3294 解析    翻译一下题意:给定n个字符串,求最长的字符串 S 的长度,使得 S 至少为其中 n/2+1 个字符串的子串, 并输出所有的S,若不存在,则输出'?'。(n<=100)    此题与 POJ3261 类似(我的 博客 ),都是相同套路,后缀数组+二分答案   当然是把每个字符串连在一起,组成一个大的字符串,再在上面建立后缀数组。但是这里有个细节,搞了我很久,为了防止我们选出的子串跨越了原来的多个字符串,需要在每个字符串中间加入不同的不会出现的字符,这样就解决了这个问题。   check的时候需要维护每个块内的$lcp$出现在多少个原来的字符串中,开一个$bool$型的$vis$数组存原字符串是否在当前块内出现,再开一个$pos$数组存长字符串的下标所属的原字符串编号,对于字符串间加入的字符的$pos$等于0, 而$vis[0]$应永远等于$true$,不能对答案产生贡献   代码: #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int maxn = 105, maxm = 1005; int n, len, cur, timer, pos[maxn*maxm], s[maxn*maxm];

【线性规划和网络流24题】

六月ゝ 毕业季﹏ 提交于 2019-12-27 03:26:08
(1)飞行员配对方案问题:二分图最大匹配。 思路:略。 View Code 1 #include<cstdio> 2 #include<cstring> 3 #define MAXN 1010 4 int cx[MAXN], cy[MAXN]; 5 int first[MAXN], next[MAXN], v[MAXN], e; 6 bool vis[MAXN]; 7 inline void addEdge(int x, int y) { 8 v[e] = y; 9 next[e] = first[x]; 10 first[x] = e++; 11 } 12 int path(int x) { 13 int i; 14 int y; 15 for (i = first[x]; i != -1; i = next[i]) { 16 y = v[i]; 17 if (!vis[y]) { 18 vis[y] = true; 19 if (cy[y] == -1 || path(cy[y])) { 20 cx[x] = y; 21 cy[y] = x; 22 return 1; 23 } 24 } 25 } 26 return 0; 27 } 28 int main() { 29 int n, m; 30 int i; 31 int x, y; 32 int ans; 33 while

[HG]奋斗赛G

橙三吉。 提交于 2019-12-26 22:36:56
T1 题目描述 安娜斯塔西娅喜欢去乌日扬迪安中央公园散步。 但她对简单的散步不感兴趣,于是她开始收集公园里的鹅卵石。 一开始,她决定收集所有她能在公园里找到的鹅卵石。 她只有两个口袋。 她能在每个口袋里同时放最多k个鹅卵石。第i种鹅卵石有w[i]个。 安娜斯塔西娅很有责任感,所以她从不把不同类型的鹅卵石混在一个口袋里。 然而,她可以把不同种类的鹅卵石放在不同的口袋。 不幸的是,她不能把所有的时间都花在收集鹅卵石上,所以她每天只能从公园里收集一次鹅卵石。 考虑到安娜斯塔西娅不能把不同类型的鹅卵石放在同一个口袋里,请帮助她找到收集乌日扬甸中央公园所有鹅卵石所需的最短天数。 解法:直接模拟 #include <cstdio> #define ll long long inline ll read(){ ll x = 0; int zf = 1; char ch = ' '; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf; } int main(){ int n =

n皇后问题<dfs>

橙三吉。 提交于 2019-12-26 14:09:30
n皇后问题指的是: n*n的国际象棋棋盘上摆放n个皇后,使其不能互相攻击, 即任意两个皇后都不能处于同一行、同一列或同一斜线上, 问有多少种摆法。 和一般n皇后问题不同的是,现在棋盘上有可能已经放了一个皇后了。 你能求出有多少合法的方案吗? 多组数据。 第一行有两个数n和m,n<=13表示棋盘大小,m<=1表示棋盘上已经有m个皇后了。 下面m行,每一行有两个数x、y(x,y< n)表示棋盘上x行y列已经有一个皇后了。 思路:打表,然后参考紫书。 #include<iostream> #include<cstdio> #include<cstring> int a[14]={0,1,0,0,2,10,4,40,92,352,724,2680,14200,73712};//打表了哈 int vis[3][30]; int n,m,x,y,ans; using namespace std; void dfs(int cur) { if(cur==n){ans++;return;} else if(cur==x) dfs(cur+1); else for(int i=0;i<n;i++) { if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]) { vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1; dfs

Card Game 【HDU - 3722】【Trie树优化+KM算法】

给你一囗甜甜゛ 提交于 2019-12-26 01:30:34
题目链接 就是说,我们可以把一个卡片贴到前面一个卡片上面,当且仅当前面卡片的后缀是你的前缀,可以得到一些覆盖,现在我们有N个卡片,我们现在想知道怎样才能使得卡片的覆盖面积数量是最大的。 首先,我们利用Trie字典树来进行优化查询的这部分,强行把原本 ,其中len代表的是字符串的长度,然后优化到了 ,这里就是一个离线的操作来进行优化了。 然后是环与KM的关系了。 #include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #include <unordered_map> #include <unordered_set> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 #define INF 0x3f3f3f3f #define HalF (l + r)>>1 #define lsn rt<<1

【日记】12.25

自作多情 提交于 2019-12-26 01:09:54
今天写了一天的题,并没有复习。 12.25 DP 1.P1140相似基因: https://www.luogu.com.cn/problem/P1140 思路: dp[i] [j]表示第一个基因的前i位和第二个基因的前j位的最大匹配,则可以从dp[i-1] [j],dp[i-1] [j-1], dp[i] [j-1]三种情况转移过来。只需要关注每次添加的字母是谁就可以了。 #include<bits/stdc++.h> using namespace std; const int M=1e2+50; struct Task{ int len1,len2,dp[M][M]; char s1[M],s2[M]; map<int,int> mp={{'A',1},{'C',2},{'G',3},{'T',4},{'-',5}}; int tr[6][6]={ {0,0,0,0,0,0}, {0,5,-1,-2,-1,-3}, {0,-1,5,-3,-2,-4}, {0,-2,-3,5,-2,-2}, {0,-1,-2,-2,5,-1}, {0,-3,-4,-2,-1,0}}; void init(){ scanf("%d%s%d%s",&len1,s1+1,&len2,s2+1); for(int i=1;i<=len1;++i) dp[i][0]=dp[i-1][0]+tr[mp[s1

10.17模拟赛(湖南集训)

白昼怎懂夜的黑 提交于 2019-12-25 09:41:00
T1 reverse 题目描述 0比1小,所以一个串中如果0全在1前面,这个串就比较和谐。对于一个只包含0和1的串,你每次可以将一个0变成1,或者将一个1变成0。那么,最少需要变多少次才能把保证所有的0在1前面呢? 输入输出格式 输入格式: 一个01串 输出格式: 一个数即答案 输入输出样例 输入样例#1: 010001 输出样例#1: 1 说明 对于40%的数据,len<=20 对于70%的数据,len<=1000 对于100%的数据,len<=10^5 题解: 我好像理解错题目了,我以为必须有1和0,好像只有1或者只有0也可以。 枚举1的数量 #include<iostream> #include<cstdio> #include<cstring> #define maxn 100009 #define inf 1000090 using namespace std; char s[maxn]; int len,cnt,tmp,p,now,ans; int main(){ freopen("reverse.in","r",stdin); freopen("reverse.out","w",stdout); scanf("%s",s+1);len=strlen(s+1); for(int i=1;i<=len;i++) if(s[i]=='1')cnt++; if(cnt==0|

p-7-19工作分配问题

不羁的心 提交于 2019-12-24 16:19:11
# include <bits/stdc++.h> using namespace std ; int minn = 99999 , a [ 22 ] [ 22 ] ; int vis [ 22 ] ; int n ; void traceback ( int x , int s ) //x代表第几份工作 { if ( x > n ) { minn = min ( minn , s ) ; return ; } for ( int i = 1 ; i <= n ; i ++ ) { if ( ! vis [ i ] ) { vis [ i ] = 1 ; if ( s + a [ x ] [ i ] < minn ) { traceback ( x + 1 , s + a [ x ] [ i ] ) ; } vis [ i ] = 0 ; } } } int main ( ) { cin >> n ; for ( int i = 1 ; i <= n ; i ++ ) { for ( int j = 1 ; j <= n ; j ++ ) cin >> a [ i ] [ j ] ; } traceback ( 1 , 0 ) ; cout << minn << endl ; return 0 ; } 来源: CSDN 作者: 星光不负赶路人~ 链接: https://blog