zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 132

    [TOC]

    Contest Info


    [Practice Link](https://atcoder.jp/contests/abc132/tasks)
    Solved A B C D E F
    6/6 O O O O Ø O
    • O 在比赛中通过
    • Ø 赛后通过
    • ! 尝试了但是失败了
    • - 没有尝试

    Solutions


    A. Fifty-Fifty

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
    	string s; cin >> s;
    	sort(s.begin(), s.end());
    	s.erase(unique(s.begin(), s.end()), s.end());
    	cout << (((int)s.size() == 2) ? "Yes" : "No") << "
    ";
    	return 0;
    }
    

    B. Ordinary Number

    #include <bits/stdc++.h>
    using namespace std;
    
    #define N 50
    int n, a[N];
    
    int main() {
    	while (scanf("%d", &n) != EOF) {
    		for (int i = 1; i <= n; ++i) {
    			scanf("%d", a + i);
    		}
    		int res = 0;
    		for (int i = 2; i < n; ++i) {
    			int f = a[i] < a[i - 1];
    			int g = a[i] < a[i + 1];
    			if (f ^ g) {
    				++res;
    			}
    		}
    		printf("%d
    ", res);
    	}
    	return 0;
    }
    

    C. Divide the Problems

    #include <bits/stdc++.h>
    using namespace std;
    
    #define N 100010
    int n, a[N];
    
    int main() {
    	while (scanf("%d", &n) != EOF) {
    		for (int i = 1; i <= n; ++i) {
    			scanf("%d", a + i);
    		}
    		sort(a + 1, a + 1 + n);
    		int mid = n / 2;
    		if (a[mid] == a[mid + 1]) {
    			puts("0");
    		} else {
    			printf("%d
    ", a[mid + 1] - a[mid]);
    		}
    	}
    	return 0;
    }
    

    D. Blue and Red Balls

    题意: 有$K$个蓝球,$N - K$个红球,询问将蓝球分成$i(1 leq i leq k)$堆,中间用红球隔开的方案数分别是多少?

    思路: 考虑先将$k$个蓝球分成$i$堆,然后每堆后面跟着一个红球,然后就有$i + 1$个空隙,剩下的红球相当于要放入$i + 1$个空箱中,允许空箱的经典问题。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define N 2010
    const int p = 1e9 + 7;
    int n, k;
    ll fac[N], inv[N];
    ll qmod(ll base, ll n) {
    	ll res = 1;
    	while (n) {
    		if (n & 1) {
    			res = res * base % p;
    		}
    		base = base * base % p;
    		n >>= 1;
    	}
    	return res;
    }
    
    ll C(int n, int m) {
    	if (n < m) return 0;
    	return fac[n] * inv[m] % p * inv[n - m] % p;
    }
    
    ll f(int n, int i, int k) {
    	ll remind = n - k;
    	if (n - k < i - 1) {
    		return 0;
    	}
    	remind -= i - 1;
    	return C(k - 1, i - 1) * C(i + remind, i) % p; 
    }
    
    int main() {
    	fac[0] = 1;
    	for (int i = 1; i <= 2000; ++i) {
    		fac[i] = fac[i - 1] * i % p;
    	}
    	inv[2000] = qmod(fac[2000], p - 2);
    	for (int i = 2000; i >= 0; --i) {
    		inv[i - 1] = inv[i] * i % p;
    	}
    	while (scanf("%d%d", &n, &k) != EOF) {
    		for (int i = 1; i <= k; ++i) {
    			printf("%lld
    ", f(n, i, k));
    		}
    	}
    	return 0;
    }
    

    E. Hopscotch Addict

    题意: 求$S$到$T$的最短路,并且要满足其长度是$3$的倍数。

    思路: $dis[i][j]$表示到第$i$个点,长度模$3$的值为$j$的最短路是多少,然后跑Dijkstra即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define N 100010
    int n, m, s, t;
    vector <vector<int>> G;
    struct node {
    	int u, w;
    	node() {}
    	node (int u, int w) : u(u), w(w) {}
    	bool operator < (const node &other) const {
    		return w > other.w;
    	}
    };
    
    int dis[N][3], used[N][3];
    void BFS() {
    	for (int i = 1; i <= n; ++i) {
    		for (int j = 0; j < 3; ++j) {
    			dis[i][j] = INF;
    			used[i][j] = 0;		
    		}
    	}
    	dis[s][0] = 0;	
    	priority_queue <node> pq;
    	pq.push(node(s, 0)); 
    	while (!pq.empty()) {
    		int u = pq.top().u, w = pq.top().w; pq.pop(); 
    		if (used[u][w % 3]) continue;
    		used[u][w % 3] = 1;
    		for (auto v : G[u]) {
    			if (dis[v][(w + 1) % 3] > w + 1) {
    				dis[v][(w + 1) % 3] = w + 1;  
    				pq.push(node(v, w + 1));  
    			}
    		}
    	}
    }
    
    int main() {
    	while (scanf("%d%d", &n, &m) != EOF) {
    		G.clear(); G.resize(n + 1);
    		for (int i = 1, u, v; i <= m; ++i) {
    			scanf("%d%d", &u, &v);
    			G[u].push_back(v);
    		}
    		scanf("%d%d", &s, &t);
    		BFS();
    		if (dis[t][0] == INF) puts("-1");
    		else {
    			printf("%d
    ", dis[t][0] / 3);
    		}
    	}
    	return 0;
    }
    

    F. Small Products

    题意: 构造一个长度为$k$的,并且相邻两数之积不超过$N$的序列的方案数是多少?

    思路: $f[i][j]$表示到第$i$位,当前位为$j$的方案数是多少。 暴力$DP$显然不行。 但是我们考虑我们每次对于$j$转移的都是$sumlimits_^{N / j} f[i - 1][j]$,考虑到$N / j$的取值只有$2sqrt$种,所以只需要存$k cdot 2sqrt$种状态。转移即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define N 110
    #define M 100010
    #define pii pair <int, int>
    #define fi first
    #define se second
    const ll p = 1e9 + 7;
    int n, k;
    ll f[N][M];
    pii g[M]; 
    map <int, int> mp;
    
    int main() {
    	while (scanf("%d%d", &k, &n) != EOF) {
    		memset(f, 0, sizeof f);
    		mp.clear();
    		int m = 0;
    		for (int i = 1, j; i <= k; i = j + 1) {
    			j = k / (k / i);
    			g[++m] = pii(j, j - i + 1);
    			mp[j] = m;
    		}
    		for (int i = 1; i <= m; ++i) {
    			f[1][i] = (f[1][i - 1] + g[i].se) % p; 
    		}
    		for (int i = 2; i <= n; ++i) {
    			for (int j = 1; j <= m; ++j) {
    				f[i][j] = (f[i][j - 1] + 1ll * g[j].se * f[i - 1][mp[k / g[j].fi]] % p) % p;
    			}
    		}
    		printf("%lld
    ", f[n][m]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    BZOJ 3205 [Apio2013]机器人 ——斯坦纳树
    BZOJ 3782 上学路线 ——动态规划 Lucas定理 中国剩余定理
    HDU 1423 Greatest Common Increasing Subsequence ——动态规划
    BZOJ 3309 DZY Loves Math ——莫比乌斯反演
    POJ 1038 Bugs Integrated, Inc. ——状压DP
    POJ 3693 Maximum repetition substring ——后缀数组
    POJ 2699 The Maximum Number of Strong Kings ——网络流
    POJ 2396 Budget ——有上下界的网络流
    BZOJ 4650 [Noi2016]优秀的拆分 ——后缀数组
    源码安装python
  • 原文地址:https://www.cnblogs.com/Dup4/p/11148059.html
Copyright © 2011-2022 走看看