标签:src div 删除 最小 strlen 有一个 经典的 push 大于
在一个队列中一次加入每一个字符,每次更新当前队列中的状态,当满足存在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 }
【8.16校内测试】【队列】【数学】【网络流/二分图最大匹配】
标签:src div 删除 最小 strlen 有一个 经典的 push 大于
原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9487069.html