【8.16校内测试】【队列】【数学】【网络流/二分图最大匹配】

在一个队列中一次加入每一个字符,每次更新当前队列中的状态,当满足存在26个不同字符时,更新答案,删除队首。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<queue>
 5 #define RG register
 6 using namespace std;
 7
 8 char s[2000005];
 9 int len, nex[2000005], flag[30];
10 int q[2000005];
11
12 int main ( ) {
13     freopen ( "str.in", "r", stdin );
14     freopen ( "str.out", "w", stdout );
15     scanf ( "%s", s );
16     len = strlen ( s );
17     for ( RG int i = 0; i < len; i ++ )
18         flag[s[i]-‘A‘] = 1;
19     int fl = 0;
20     for ( RG int i = 0; i < 26; i ++ )
21         if ( !flag[i] ) {
22             fl = 1; break;
23         }
24     if ( fl ) {
25         printf ( "QwQ" );     return 0;
26     }
27     int num = 0, ans = 0x3f3f3f3f, h = 0, t = 0;
28     memset ( flag, 0, sizeof ( flag ) );
29     for ( RG int i = 0; i < len; i ++ ) {
30         q[++t] = s[i]-‘A‘; flag[s[i]-‘A‘] ++;
31         if ( flag[s[i]-‘A‘] == 1 ) num ++;
32         while ( t-h && num == 26 ) {
33             ans = min ( ans, t-h );
34             int x = q[h+1]; h ++;
35             flag[x] --;
36             if ( !flag[x] ) num --;
37         }
38     }
39     printf ( "%d", ans );
40 }

一开始想的分解质因数,再通过每个质因子的个数来判断是否成立,可是一开始就错了...以为1e9开方是1e3...

方法是先将x和y乘起来,因为题目有一个性质,他们的乘积一定是一个数的3次方,设这个数为k,因为x和y中每次游戏要不是有一个k1值,要不是有两个,所以x和y必然可以整除k。三个判断条件即可。【注意】二分求k值时不能让k大于1e6,三方爆long long。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #define ll long long
 5 using namespace std;
 6
 7 ll x, y;
 8 int num1[400001], num2[400001];
 9 int prime[400001], tot, isnot[400001];
10
11 void read ( ll &x ) {
12     x = 0; char ch = getchar ( ); int t = 1;
13     while ( ch > ‘9‘ || ch < ‘0‘ ) {
14         if ( ch == ‘-‘ ) t = -1; ch = getchar ( );
15     }
16     while ( ch >= ‘0‘ && ch <= ‘9‘ ) {
17         x = x * 10 + ch - ‘0‘;
18         ch = getchar ( );
19     }
20     x = x * t;
21 }
22
23 inline int gcd ( int a, int b ) {
24     return b == 0 ? a : gcd ( b, a % b );
25 }
26
27 ll erfen ( ll qwq ) {
28     ll l = 1, r = min ( sqrt ( qwq ), 1e6 ), res;
29     while ( l <= r ) {
30         ll mid = ( l + r ) >> 1;
31         if ( mid * mid * mid <= qwq ) {
32             l = mid + 1; res = mid;
33         } else r = mid - 1;
34     }
35     return res;
36 }
37
38 int main ( ) {
39     freopen ( "game.in", "r", stdin );
40     freopen ( "game.out", "w", stdout );
41     int T;
42     scanf ( "%d", &T );
43     while ( T -- ) {
44         int fl = 0;
45         read ( x ); read ( y );
46         ll g = 1ll * x * y;
47         ll qwq = erfen ( g );
48         if ( qwq * qwq * qwq != g ) fl = 1;
49         if ( x % qwq != 0 || y % qwq != 0 ) fl = 1;
50         if ( fl ) printf ( "No\n" );
51         else printf ( "Yes\n" );
52     }
53     return 0;
54 }

比较经典的一道题,分别把按行放木板和按列放木板给每一块泥地标号,可以连着放的号数一样。把每一个泥地的行号连向列号,跑最小割或者最大匹配即可。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 #define inf 0x3f3f3f3f
  6 using namespace std;
  7
  8 int r, c;
  9 char a[55][55];
 10 int num1[55][55], num2[55][55], cnt1, cnt2, s, t;
 11
 12 int stot = 1, h[10005], tov[200005], nex[200005], f[200005], hh[10005];
 13 void add ( int u, int v, int ff ) {
 14     tov[++stot] = v;
 15     f[stot] = ff;
 16     nex[stot] = h[u];
 17     h[u] = stot;
 18
 19     tov[++stot] = u;
 20     f[stot] = 0;
 21     nex[stot] = h[v];
 22     h[v] = stot;
 23 }
 24
 25 int dep[1005], vis[1005];
 26 queue < int > q;
 27 bool bfs ( ) {
 28     memset ( dep, 0, sizeof ( dep ) );
 29     memset ( vis, 0, sizeof ( vis ) );
 30     q.push ( s );    vis[s] = 1;
 31     while ( !q.empty ( ) ) {
 32         int u = q.front ( ); q.pop ( );
 33         for ( int i = h[u]; i; i = nex[i] ) {
 34             int v = tov[i];
 35             if ( !vis[v] && f[i] ) {
 36                 dep[v] = dep[u] + 1;
 37                 vis[v] = 1;
 38                 q.push ( v );
 39             }
 40         }
 41     }
 42     return vis[t];
 43 }
 44
 45 int dfs ( int u, int delta ) {
 46     if ( u == t ) return delta;
 47     int res = 0;
 48     for ( int i = hh[u]; i && delta; i = nex[i] ) {
 49         int v = tov[i];
 50         if ( dep[v] == dep[u] + 1 && f[i] ) {
 51             int dd = dfs ( v, min ( f[i], delta ) );
 52             f[i] -= dd;
 53             f[i^1] += dd;
 54             delta -= dd;
 55             res += dd;
 56             hh[u] = i;
 57         }
 58     }
 59     return res;
 60 }
 61
 62 void debug ( ) {
 63     for ( int i = 0; i < r; i ++ ) {
 64         for ( int j = 0; j < c; j ++ )
 65             printf ( "%d ", num1[i][j] );
 66         cout << endl;
 67     }
 68     cout << endl;
 69     for ( int i = 0; i < r; i ++ ) {
 70         for ( int j = 0; j < c; j ++ )
 71             printf ( "%d ", num2[i][j] );
 72         cout << endl;
 73     }
 74 }
 75
 76 int main ( ) {
 77     freopen ( "cover.in", "r", stdin );
 78     freopen ( "cover.out", "w", stdout );
 79     scanf ( "%d%d", &r, &c );
 80     for ( int i = 0; i < r; i ++ )
 81         scanf ( "%s", a[i] );
 82     for ( int i = 0; i < r; i ++ )
 83         for ( int j = 0; j < c; j ++ ) {
 84             if ( j != 0 && a[i][j] == ‘*‘ && a[i][j-1] == ‘*‘ )     num1[i][j] = num1[i][j-1];
 85             else if ( a[i][j] == ‘*‘ ){
 86                 cnt1 ++;    num1[i][j] = cnt1;
 87             }
 88             if ( i != 0 && a[i][j] == ‘*‘ && a[i-1][j] == ‘*‘ )     num2[i][j] = num2[i-1][j];
 89             else if ( a[i][j] == ‘*‘ ){
 90                 cnt2 ++;     num2[i][j] = cnt2;
 91             }
 92         }
 93     //debug ( );
 94     for ( int i = 0; i < r; i ++ )
 95         for ( int j = 0; j < c; j ++ )
 96             if ( a[i][j] == ‘*‘ ) {
 97                 //printf ( "%d->%d+%d\n", num1[i][j], num2[i][j], cnt1 );
 98                 add ( num1[i][j], num2[i][j] + cnt1, 1 );
 99             }
100     s = 0, t = cnt1+cnt2+1;
101     for ( int i = 1; i <= cnt1; i ++ )
102         add ( s, i, 1 );
103     for ( int i = 1; i <= cnt2; i ++ )
104         add ( i + cnt1, t, 1 );
105     int ans = 0;
106     while ( bfs ( ) ) {
107         for ( int i = 0; i <= cnt1 + cnt2 + 1; i ++ )
108             hh[i] = h[i];
109         ans += dfs ( s, 0x3f3f3f3f );
110     }
111     printf ( "%d", ans );
112     return 0;
113 }

原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9487069.html

时间: 2024-08-04 20:54:50

【8.16校内测试】【队列】【数学】【网络流/二分图最大匹配】的相关文章

【网络流-二分图最大匹配】poj3041Asteroids

/* 这道题将每行x看成是结点x,没列y看成是结点y,而障碍物的坐标xy看成是从x到y的 一条边.建图后问题就变成了,找最少的点,使得这些点与所有的边相邻,即最小 点覆盖,用匈牙利算法解决. ------------------------------- 定理:最小点覆盖数 = 最大匹配数,即求图的最大匹配即可,匈牙利算法 ------------------------------- 模板讲解: bool find(int v) { for(int i=1; i<=n; i++) { if(g

图论——LCA、强联通分量、桥、割顶、二分图最大匹配、网络流

A: 交通运输线 时间限制: 5 Sec  内存限制: 128 MB 题目描述 战后有很多城市被严重破坏,我们需要重建城市.然而,有些建设材料只能在某些地方产生.因此,我们必须通过城市交通,来运送这些材料的城市.由于大部分道路已经在战争期间完全遭到破坏,可能有两个城市之间没有道路.当然在运输线中,更不可能存在圈. 现在,你的任务来了.给你战后的道路情况,我们想知道,两个城市之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度. 输入 第一行一个整数Case(Case<=10)表示测试数据

【网络流#6】POJ 3041 Asteroids 二分图最大匹配 - 《挑战程序设计竞赛》例题

学习网络流中ing...作为初学者练习是不可少的~~~构图方法因为书上很详细了,所以就简单说一说 把光束作为图的顶点,小行星当做连接顶点的边,建图,由于 最小顶点覆盖 等于 二分图最大匹配 ,因此求二分图最大匹配即可. 邻接矩阵,DFS寻找增广路,匈牙利算法 邻接矩阵:复杂度O(n^3) 如果使用邻接表:复杂度O(n*m) #include<cstdio> #include<cstring> #include<cmath> #include<iostream>

软件测试的16种测试类型

软件测试的16种测试类型 软件测试主要从以下16种类型进行测试: 一:功能测试(10个方面) 菜单.工具栏.快捷键.下拉框.按钮.单选按钮.复选按钮.切换.链接.触发键 二:界面测试 登陆界面.总界面.输入界面(增.删.改.查).处理界面.输出界面.报表界面.提示界面 三:容错测试 数据长度.数据类型.非法此操作 四:接口测试 接口测试也叫业务流程测试(包括功能模块之间.模块与模块之间.子系统之间) 内部接口:例如:导入.导出(通俗的讲是接口就是调用) 外部接口: 五:性能测试(TPS吞吐量.响

【wikioi】1922 骑士共存问题(网络流/二分图匹配)

用匈牙利tle啊喂?和网络流不都是n^3的吗.... (更新:what!!!!!!发现个无语的问题,.!!!!结构比数组快啊orz,这节奏不对啊....以后图都写结构的节奏啊... #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> using namespace

二分图最大匹配[网络流]

题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 输出格式: 共一行,二分图最大匹配 建模: s--1-->X--1-->Y--1-->t 注意:边的数量 PS:本题比hungary快了5倍 // // main.cpp // 二分图dinic // // Created by Candy on 29/11/2016. // Copyri

网络流之二分图最大匹配

前言:二分图最大匹配往往用于普通的指派问题中,可转换为最大流问题求解,也可以利用二分图的性质及其边的容量为1的特点,简单的实现二分图的最大匹配算法. 问题模型:有n台计算机和k个任务,每台计算机处理的任务种类不同,问如果给每台计算机分配一个任务,一次最多能处理多少个任务. 分析:该问题可以转化为图论模型来分析.设U为所有计算机顶点的集合,V为所有任务类型的集合,u属于U,v属于V,e=(u,v)表示计算机u能处理任务v,E是所有e的集合. 则G=(U||V, E),且G中满足两两不含公共端点的边

UOJ #78 二分图最大匹配

#78. 二分图最大匹配 从前一个和谐的班级,有 nl 个是男生,有 nr 个是女生.编号分别为 1,…,nl 和 1,…,nr. 有若干个这样的条件:第 v 个男生和第 u 个女生愿意结为配偶. 请问这个班级里最多产生多少对配偶? 输入格式 第一行三个正整数,nl,nr,m. 接下来 m 行,每行两个整数 v,u 表示第 v 个男生和第 u 个女生愿意结为配偶.保证 1≤v≤nl,1≤u≤nr,保证同一个条件不会出现两次. 输出格式 第一行一个整数,表示最多产生多少对配偶. 接下来一行 nl 

二分图最大匹配及常用建图方法

转载百度文库 算法---艺术 二分图匹配剖析 很多人说,算法是一种艺术.但是对于初学者的我,对算法认识不是很深刻,但偶尔也能感受到他强大的魅力与活力. 这让我追求算法的脚步不能停止.下面我通过分析匈牙利算法以及常用建图方式,与大家一起欣赏算法的美. 匈牙利算法 匈牙利算法是用来解决最大二分图匹配问题的,所谓二分图即 "一组点集可以分为两部分,且每部分内各点互不相连,两部分的点之间可以有边".所谓最大二分图匹配即 "对于二分图的所有边,寻找一个子集,这个子集满足两个条件, 1: