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

    A. Odd Selection

    网址:https://codeforces.com/contest/1363/problem/A

    Shubham has an array a of size n, and wants to select exactly x elements from it, such that their sum is odd. These elements do not have to be consecutive. The elements of the array are not guaranteed to be distinct.

    Tell him whether he can do so.

    Input

    The first line of the input contains a single integer t (1≤t≤100) — the number of test cases. The description of the test cases follows.

    The first line of each test case contains two integers n and x (1≤x≤n≤1000) — the length of the array and the number of elements you need to choose.

    The next line of each test case contains n integers a1,a2,…,an (1≤ai≤1000) — elements of the array.

    Output

    For each test case, print "Yes" or "No" depending on whether it is possible to choose x elements such that their sum is odd.

    You may print every letter in any case you want.

    Example
    input
    5
    1 1
    999
    1 1
    1000
    2 1
    51 50
    2 2
    51 50
    3 3
    101 102 103
    
    output
    Yes
    No
    Yes
    Yes
    No
    
    Note

    For 1st case: We must select element 999, and the sum is odd.

    For 2nd case: We must select element 1000, so overall sum is not odd.

    For 3rd case: We can select element 51.

    For 4th case: We must select both elements 50 and 51 — so overall sum is odd.

    For 5th case: We must select all elements — but overall sum is not odd.

    果然考察算法基本功。

    当时做麻烦了。其实不妨考虑:和为奇数时累加奇数的个数k必为奇数。统计该序列中奇数的个数,以及偶数的个数。分别记为odd_num,even_num;

    每次选择k个奇数,当x - k <= even_num时存在。

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int maxn = 1000 + 5;
    int n, x, a[maxn];
    int main()
    {
    	int T;
    	scanf("%d", &T);
    	while(T --)
    	{
    		memset(a, 0, sizeof(a));
    		int odd_num = 0, even_num = 0;
    		scanf("%d %d", &n, &x);
    		for(int i = 1; i <= n; ++ i)
    		{
    			scanf("%d", &a[i]);
    			if(a[i] & 1) ++ odd_num;
    			else ++ even_num;
    		}
    		bool ok = 0;
    		for(int i = 1; i <= min(x, odd_num); i += 2)
    		{
    			if(even_num >= x - i)
    			{
    				ok = 1;
    				puts("Yes");
    				break;
    			}
    		}
    		if(ok == false) puts("No");
    	}
    	return 0;
    }
    

    B. Subsequence Hate

    网址:https://codeforces.com/contest/1363/problem/B

    Shubham has a binary string s. A binary string is a string containing only characters "0" and "1".

    He can perform the following operation on the string any amount of times:

    Select an index of the string, and flip the character at that index. This means, if the character was "0", it becomes "1", and vice versa.
    A string is called good if it does not contain "010" or "101" as a subsequence — for instance, "1001" contains "101" as a subsequence, hence it is not a good string, while "1000" doesn't contain neither "010" nor "101" as subsequences, so it is a good string.

    What is the minimum number of operations he will have to perform, so that the string becomes good? It can be shown that with these operations we can make any string good.

    A string a is a subsequence of a string b if a can be obtained from b by deletion of several (possibly, zero or all) characters.

    Input

    The first line of the input contains a single integer t (1≤t≤100) — the number of test cases.

    Each of the next t lines contains a binary string s (1≤|s|≤1000).

    Output

    For every string, output the minimum number of operations required to make it good.

    Example
    input
    7
    001
    100
    101
    010
    0
    1
    001100
    
    output
    0
    0
    1
    1
    0
    0
    2
    
    Note

    In test cases 1, 2, 5, 6 no operations are required since they are already good strings.

    For the 3rd test case: "001" can be achieved by flipping the first character — and is one of the possible ways to get a good string.

    For the 4th test case: "000" can be achieved by flipping the second character — and is one of the possible ways to get a good string.

    For the 7th test case: "000000" can be achieved by flipping the third and fourth characters — and is one of the possible ways to get a good string.

    题目让我们将序列分两半。那就枚举每一个位置为界线取最值。

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn = 1000 + 10, INF = 1 << 30;
    char s[maxn];
    int sum, L_sum[maxn], R_sum[maxn];
    int main()
    {
    	int T;
    	scanf("%d", &T);
    	while(T --)
    	{
    		int n;
    		memset(L_sum, 0, sizeof(L_sum));
    		memset(R_sum, 0, sizeof(R_sum));
    		scanf("%s", (s + 1));
    		n = strlen(s + 1);
    		int sum = INF;
    		for(int i = 1; i <= n; ++ i)
    		{
    			L_sum[i] = L_sum[i - 1] + s[i] - '0';
    		}
    		
    		for(int i = n; i; -- i)
    		{
    			R_sum[i] = R_sum[i + 1] + s[i] - '0';
    		}
    		for(int i = 1; i <= n; ++ i)
    		{
    			sum = min(sum, min(L_sum[i], i - L_sum[i]) + min(R_sum[i + 1], n - i - R_sum[i + 1]));
    		}
    		printf("%d
    ", sum);
    	}
    	return 0;
    }
    

    C. Game On Leaves

    网址:https://codeforces.com/contest/1363/problem/C

    time limit per test2 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Ayush and Ashish play a game on an unrooted tree consisting of n nodes numbered 1 to n. Players make the following move in turns:

    • Select any leaf node in the tree and remove it together with any edge which has this node as one of its endpoints. A leaf node is a node with degree less than or equal to 1.
      A tree is a connected undirected graph without cycles.

    There is a special node numbered x. The player who removes this node wins the game.

    Ayush moves first. Determine the winner of the game if each player plays optimally.

    Input

    The first line of the input contains a single integer t (1≤t≤10) — the number of testcases. The description of the test cases follows.

    The first line of each testcase contains two integers n and x (1≤n≤1000,1≤x≤n) — the number of nodes in the tree and the special node respectively.

    Each of the next n−1 lines contain two integers u, v (1≤u,v≤n, u≠v), meaning that there is an edge between nodes u and v in the tree.

    Output

    For every test case, if Ayush wins the game, print "Ayush", otherwise print "Ashish" (without quotes).

    Examples
    input
    1
    3 1
    2 1
    3 1
    
    output
    Ashish
    
    input
    1
    3 2
    1 2
    1 3
    
    output
    Ayush
    
    Note

    For the 1st test case, Ayush can only remove node 2 or 3, after which node 1 becomes a leaf node and Ashish can remove it in his turn.

    For the 2nd test case, Ayush can remove node 2 in the first move itself.

    这道题首先从特殊情况入手:

    • 当节点x为叶子节点时,先手比赢;
    • 当节点x度数大于1时,不管怎样,只有当它度数为1时才可以判定。最优策略等价于每人不进行能够使节点x度数为1的操作(除了万不得已)。我们可以通过n的奇偶性判断谁最后胜利。
    • 即当n为奇数的时候,后手必赢。同理,不加赘述了。
      代码如下:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn = 1000 + 5;
    int n, x, deg[maxn];
    int main()
    {
    	int T;
    	scanf("%d", &T);
    	while(T --)
    	{
    		scanf("%d %d", &n, &x);
    		int u, v;
    		memset(deg, 0, sizeof(deg));
    		for(int i = 1; i < n; ++ i)
    		{
    			scanf("%d %d", &u, &v);
    			++ deg[u];
    			++ deg[v];
    		}
    		if(deg[x] < 2) puts("Ayush");
    		else if(n & 1) puts("Ashish");
    		else puts("Ayush");
    	}
    	return 0;
    }
    

    D. Guess The Maximums

    网址:https://codeforces.com/contest/1363/problem/D

    E. Tree Shuffling

    网址:https://codeforces.com/contest/1363/problem/E

    Ashish has a tree consisting of n nodes numbered 1 to n rooted at node 1. The i-th node in the tree has a cost ai, and binary digit bi is written in it. He wants to have binary digit ci written in the i-th node in the end.

    To achieve this, he can perform the following operation any number of times:

    Select any k nodes from the subtree of any node u, and shuffle the digits in these nodes as he wishes, incurring a cost of k⋅au. Here, he can choose k ranging from 1 to the size of the subtree of u.
    He wants to perform the operations in such a way that every node finally has the digit corresponding to its target.

    Help him find the minimum total cost he needs to spend so that after all the operations, every node u has digit cu written in it, or determine that it is impossible.

    Input

    First line contains a single integer n ((1≤n≤2⋅10^5)) denoting the number of nodes in the tree.

    i-th line of the next n lines contains 3 space-separated integers ai, bi, ci ((1≤ai≤10^9,0≤bi,ci≤1)) — the cost of the i-th node, its initial digit and its goal digit.

    Each of the next n−1 lines contain two integers u, v (1≤u,v≤n, u≠v), meaning that there is an edge between nodes u and v in the tree.

    Output

    Print the minimum total cost to make every node reach its target digit, and −1 if it is impossible.

    Examples
    input
    5
    1 0 1
    20 1 0
    300 0 1
    4000 0 0
    50000 1 0
    1 2
    2 3
    2 4
    1 5
    
    output
    4
    
    input
    5
    10000 0 1
    2000 1 0
    300 0 1
    40 0 0
    1 1 0
    1 2
    2 3
    2 4
    1 5
    
    output
    24000
    
    input
    2
    109 0 1
    205 0 1
    1 2
    
    output
    -1
    
    Note

    The tree corresponding to samples 1 and 2 are:

    image

    In sample 1, we can choose node 1 and k=4 for a cost of 4⋅1 = 4 and select nodes 1,2,3,5, shuffle their digits and get the desired digits in every node.

    In sample 2, we can choose node 1 and k=2 for a cost of 10000⋅2, select nodes 1,5 and exchange their digits, and similarly, choose node 2 and k=2 for a cost of 2000⋅2, select nodes 2,3 and exchange their digits to get the desired digits in every node.

    In sample 3, it is impossible to get the desired digits, because there is no node with digit 1 initially.

    这道题明确一点:节点祖先不影响节点的操作。

    换句话说,我们可以通过这样的调整:a[i] = min(a[i], a[fa[i]]);

    接下来,不断递归即可。

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int maxn = 200000 + 5;
    vector <int> G[maxn];
    int n, a[maxn], b[maxn], c[maxn];
    long long ans = 0;
    void dfs(int u, int Fa)
    {
    	a[u] = min(a[u], a[Fa]);
    	int size1 = 0, size2 = 0;
    	for(int i = 0; i < G[u].size(); ++ i)
    	{
    		int v = G[u][i];
    		if(v != Fa)
    		{
    			dfs(v, u);
    			if(b[v] < 0) size2 -= b[v];
    			else size1 += b[v];
    		}
    	}
    	if(b[u] > 0) ++ size1;
    	if(b[u] < 0) ++ size2;
    	b[u] = size1 - size2;
    	ans += (long long) min(size1, size2) * a[u] << 1ll;
    	return;
    }
    int main()
    {
    	scanf("%d", &n);
    	a[0] = 1 << 30;
    	for(int i = 0; i <= n; ++ i) G[i].clear();
    	int x1 = 0, x2 = 0;
    	for(int i = 1; i <= n; ++ i)
    	{
    		scanf("%d %d %d", &a[i], &b[i], &c[i]);
    		x1 += b[i], x2 += c[i];
    		b[i] -= c[i];
    	}
    	if(x1 != x2) puts("-1");
    	else
    	{
    		int u, v;
    		for(int i = 1; i < n; ++ i)
    		{
    			scanf("%d %d", &u, &v);
    			G[u].push_back(v);
    			G[v].push_back(u);
    		}
    		dfs(1, 0);
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    穷举 迭代 while
    for 循环
    switch case
    if else 语句
    数据类型
    语句的输入、输出
    控件——DataGridview
    mysql-bin.000001文件的来源及处理方法
    /var/log目录下的20个Linux日志文件功能详解
    CountDownLatch
  • 原文地址:https://www.cnblogs.com/zach20040914/p/13099252.html
Copyright © 2011-2022 走看看