zoukankan      html  css  js  c++  java
  • Codeforces Round #592 (Div. 2)

    传送门

    A. Pens and Pencils

    签到。

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    // #define Local
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 1e5 + 5;
     
    int a, b, c, d, k;
     
    void run() {
    	cin >> a >> b >> c >> d >> k;
    	for(int x = 1; x < k; x++) {
    		int y = k - x;
    		if(x * c >= a && y * d >= b) {
    			cout << x << ' ' << y << '
    ';
    			return;
    		}
    	}
    	cout << -1 << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    

    B. Rooms and Staircases

    签到。

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    // #define Local
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 1005;
     
    int n;
    char s[N];
     
    void run() {
    	cin >> n;
    	cin >> (s + 1);
    	int left = -1, right;
    	for(int i = 1; i <= n; i++) {
    		if(s[i] == '1') {
    			left = i; break;
    		}
    	}
    	for(int i = n; i >= 1; i--) {
    		if(s[i] == '1') {
    			right = i; break;
    		}
    	}
    	int ans = 0;
    	if(left == -1) {
    		ans = n;
    	} else {
    		ans = max(2 * right, 2 * (n - left + 1));
    	}
    	cout << ans << '
    ';
    } 
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    

    C. The Football Season

    题意:
    现在共有(n,nleq 10^{12})场比赛,赢一场比赛获得(w)分,平局获得(d)分,输了不加分,(1leq d<wleq 10^5)
    现在知道总分(p,pleq 10^{17}),求三元组((x,y,z))满足:

    • (xcdot w+ycdot d=p)
    • (x+y+z=n)

    不存在则输出(-1)

    思路:
    这不是扩欧模板题吗?也不是那么模板,还要贪心一下求个最小解,所以就卡了一整场比赛。
    因为(d<w),那么可以知道(y< w),因为当(ygeq w)时,(w)(d)不如(x=d)时,(d)(w)划算。
    然后(w)的范围也比较小,所以直接枚举判断就是了。

    或者这样思考:反正是求较小解,那么得到解过后,(y)会模上(w),也就是说自然(y)的范围就比较小了。为什么是(y)模,因为(x)越多总数量越小~

    感觉还是挺巧妙的QAQ,没有细心分析题目性质以及数据范围。
    所以说模板题不可信!!

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    // #define Local
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 1e5 + 5;
     
    ll n, p, w, d;
     
    void run() {
    	for(int y = 0; y < w; y++) {
    		if(p - y * d < 0) break;
    		if((p - y * d) % w == 0) {
    			ll x = (p - y * d) / w;
    			if(n - x - y >= 0) {
    				cout << x << ' ' << y << ' ' << n - x - y << '
    ';
    				return;
    			}
    		}
    	}
    	cout << -1 << '
    ';
    	return;
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(cin >> n >> p >> w >> d) run();
        return 0;
    }
    

    D. Paint the Tree

    容易发现只有链的情况合法,链的情况就很简单了。
    因为颜色个数较少,所以直接枚举颜色排列染色就行。

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    // #define Local
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 1e5 + 5;
     
    int n;
    int c[3][N];
    int a[N], d[N], color[N], tmp[N];
    vector <int> g[N];
    int T;
     
    void dfs(int u, int fa) {
    	a[++T] = u;
    	for(auto v : g[u]) {
    		if(v == fa) continue;
    		dfs(v, u);
    	}
    }
     
    void run() {
    	for(int i = 1; i <= n; i++) {
    		d[i] = 0;
    		g[i].clear();
    	}
    	T = 0;
    	for(int i = 0; i < 3; i++) {
    		for(int j = 1; j <= n; j++) {
    			cin >> c[i][j];
    		}
    	}
    	for(int i = 1; i < n; i++) {
    		int u, v; cin >> u >> v;
    		++d[u], ++d[v];
    		g[u].push_back(v), g[v].push_back(u);
    	}
    	for(int i = 1; i <= n; i++) {
    		if(d[i] >= 3) {
    			cout << -1 << '
    ';
    			return;
    		}
    	}
    	int rt;
    	for(int i = 1; i <= n; i++) {
    		if(d[i] == 1) rt = i;
    	}
    	dfs(rt, 0);
    	int col[3] = {0, 1, 2};
    	ll ans = 1e18;
    	do {
    		ll res = 0;
    		for(int i = 1; i <= n; i++) {
    			res += c[col[(i - 1) % 3]][a[i]];
    			tmp[a[i]] = col[(i - 1) % 3];
    		}
    		if(res < ans) {
    			ans = res;
    			memcpy(color, tmp, sizeof(color));
    		}
    	} while(next_permutation(col, col + 3));
    	cout << ans << '
    ';
    	for(int i = 1; i <= n; i++) cout << color[i] + 1 << " 
    "[i == n];
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(cin >> n) run();
        return 0;
    }
    

    E. Minimizing Difference

    题意:
    给出(n)个数,现在你可以执行不超过(k)次操作,每次操作可以让一个数加一或者减一。
    问最后最大与最小值的差值最小是多少。

    思路:

    • 显然差值具有单调性,可以考虑二分差值。
    • 注意到最终最优的情况中,一定存在某个数其没有发生改变。
    • 那么直接枚举下界和上界,二分找另外一个界限就行(也可以利用双指针)。

    至于为什么可以一定存在某个数不会改变,可以这样考虑:
    若最终存在至少两个不同的数,那肯定满足;
    若最终是只有一个值,那么一定会达到只有两个值的状态,我们固定一个数量较多的不变就行,不影响结果。

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    // #define Local
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 1e5 + 5;
     
    ll n, k;
    int a[N];
    ll sum[N];
     
    bool chk(int d) {
    	for(int i = 1; i <= n; i++) {
    		int low = lower_bound(a + 1, a + n + 1, a[i]) - a - 1;
    		int high = upper_bound(a + 1, a + n + 1, a[i] + d) - a;
    		ll tot = 1ll * low * a[i] - sum[low] + sum[n] - sum[high - 1] - 1ll * (n - high + 1) * (a[i] + d);
    		if(tot <= k) return true;
    	}
    	for(int i = 1; i <= n; i++) {
    		int high = upper_bound(a + 1, a + n + 1, a[i]) - a;
    		int low = lower_bound(a + 1, a + n + 1, a[i] - d) - a - 1;
    		ll tot = 1ll * low * (a[i] - d) - sum[low] + sum[n] - sum[high - 1] - 1ll * (n - high + 1) * a[i];
    		if(tot <= k) return true;
    	}
    	return false;
    }
     
    void run() {
    	for(int i = 1; i <= n; i++) cin >> a[i];
    	sort(a + 1, a + n + 1);
    	for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + a[i];
    	int l = 0, r = 1e9 + 1, mid;
    	while(l < r) {
    		mid = (l + r) >> 1;
    		if(chk(mid)) r = mid;
    		else l = mid + 1;
    	}
    	cout << l << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(cin >> n >> k) run();
        return 0;
    }
    

    F. Chips

    题意:
    给出一个只有黑白两种颜色的环,然后执行(k)次操作,每次操作,对于每个位置,若其两边的颜色和它不同,它的颜色就发生改变。
    (k)次过后的颜色状态是什么。
    注意一下,每次操作中,颜色改变是同时的。

    思路:
    关键在于连续的段,很容易发现颜色连续的段颜色不会发生改变。
    那么我们将所有连续的段提取出来,每次单独考虑两个连续段的中间部分,将(k)(len)(min)暴力修改即可。
    易知复杂度不超过(O(n))
    注意一下因为是环,开头和结尾的部分不是很好处理,所以可以将序列复制两次,最后只看中间部分,这样就比较方便处理。

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    // #define Local
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 2e5 + 5;
     
    int n, k;
    char s[3 * N];
     
    struct seg{
    	int l, r, c;
    }a[N];
     
    void run() {
    	cin >> (s + 1);
    	for(int j = n + 1; j <= 3 * n; j++) {
    		s[j] = s[j - n];
    	}
    	s[3 * n + 1] = '';
    	int tot = 0;
    	for(int i = 1, j; i <= 3 * n; i = j) {
    		j = i + 1;
    		while(j <= 3 * n && s[i] == s[j]) ++j;
    		int col = (s[i] == 'W' ? 0 : 1);
    		if(j - i > 1)
    			a[++tot] = {i, j - 1, col};
    	}
    	// for(int i = 1; i <= tot; i++) {
    	// 	cout << a[i].l << ' ' << a[i].r << '
    ';
    	// }
    	for(int i = 1; i < tot; i++) {
    		int len = a[i + 1].l - 1 - a[i].r;
    		if(a[i].c == a[i + 1].c) {
    			if(len - 2 * k > 0) {
    				for(int j = a[i].r + 1; j <= a[i].r + k; j++) {
    					s[j] = (a[i].c == 0 ? 'W' : 'B');
    				}
    				for(int j = a[i + 1].l - 1; j >= a[i + 1].l - k; j--) {
    					s[j] = (a[i].c == 0 ? 'W' : 'B');
    				}
    				for(int j = a[i].r + k + 1; j <= a[i + 1].l - k - 1; j++) {
    					s[j] = (s[j - 1] == 'W' ? 'B' : 'W');
    				}
    			} else {
    				for(int j = a[i].r + 1; j <= a[i + 1].l - 1; j++) {
    					s[j] = (a[i].c == 0 ? 'W' : 'B');
    				}
    			}
    		} else {
    			if(len - 2 * k > 0) {
    				for(int j = a[i].r + 1; j <= a[i].r + k; j++) {
    					s[j] = (a[i].c == 0 ? 'W' : 'B');
    				}
    				for(int j = a[i + 1].l - 1; j >= a[i + 1].l - k; j--) {
    					s[j] = (a[i + 1].c == 0 ? 'W' : 'B');
    				}
    				for(int j = a[i].r + k + 1; j <= a[i + 1].l - k - 1; j++) {
    					s[j] = (s[j - 1] == 'W' ? 'B' : 'W');
    				}
    			} else {
    				for(int j = a[i].r + 1; j <= a[i].r + len / 2; j++) {
    					s[j] = (a[i].c == 0 ? 'W' : 'B');
    				}
    				for(int j = a[i + 1].l - 1; j >= a[i + 1].l - len / 2; j--) {
    					s[j] = (a[i + 1].c == 0 ? 'W' : 'B');
    				}				
    			}			
    		}
    	}
    	if(tot == 0 && k & 1) {
    		for(int i = n + 1; i <= 2 * n; i++) {
    			s[i] = (s[i] == 'W' ? 'B' : 'W');
    		}
    	}
    	for(int i = n + 1; i <= 2 * n; i++) {
    		cout << s[i];
    	}
    	cout << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(cin >> n >> k) run();
        return 0;
    }
    

    G. Running in Pairs

    题意:
    给出两个排列(p,q),先可以任意调换排列的顺序,求最大的(sum_{i=1}^{n}max(p_i,q_i)),同时其不能超过(k)

    思路:

    • 观察可以发现,在所有的(max(p_i,q_i))中,同一个数最多出现两次。
    • 采用贪心策略,应尽可能接近(k),所以每次将目前最大和最小的交换。
    • 若交换过后值超过(k),因为交换产生的贡献是连续的,所以我们选取中间最优的进行交换即可。

    这G貌似有点简单。。。就是一个普通的贪心。。

    Code
    #include <bits/stdc++.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    // #define Local
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 1e6 + 5;
     
    ll n, k;
    int a[N], b[N];
     
    void run() {
    	ll ans = (n + 1) * n / 2;
    	if(ans > k) {
    		cout << -1 << '
    ';
    		return;
    	}
    	for(int i = 1; i <= n; i++) a[i] = b[i] = i;
    	int p = n / 2;
    	int now = n - 1, pos = 1;
    	for(int i = 1; i <= p; i++) {
    		if(ans + now > k) {
    			swap(a[pos], a[pos + k - ans]);
    			break;
    		}
    		ans += now;
    		now -= 2;
    		swap(a[pos], a[n - pos + 1]);
    		++pos;
    	}
    	ll sum = 0;
    	for(int i = 1; i <= n; i++) sum += max(a[i], b[i]);
    	cout << sum << '
    ';
    	for(int i = 1; i <= n; i++) cout << a[i] << " 
    "[i == n];
    	for(int i = 1; i <= n; i++) cout << b[i] << " 
    "[i == n];
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
    #ifdef Local
        freopen("../input.in", "r", stdin);
        freopen("../output.out", "w", stdout);
    #endif
        while(cin >> n >> k) run();
        return 0;
    }
    
  • 相关阅读:
    02
    01
    Redis、Mongo
    Django
    Django
    Django
    Django
    7.2
    Django
    contenttypes
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/11672939.html
Copyright © 2011-2022 走看看