zoukankan      html  css  js  c++  java
  • AtCoder Grand Contest 010 题解

    A - Addition

    如果奇数的个数是奇数就无解,否则就有解。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    int n, ans; 
     
    int main()
    {
    	gi(n);
    	for (int i = 1; i <= n; ++i)
    	{
    		int x = F();
    		if (x & 1) ++ans;
    	}
    	if (ans & 1) puts("NO");
    	else puts("YES");
    }
    

      

    B - Boxes

    模拟,计算出以这个开头的操作有多少次,然后判断一下是不是可以完成。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    int64 n, a[100010], b[100010], x[100010];
     
    int64 s = 0;
     
    int main()
    {
    	gi(n);
    	for (int i = 1; i <= n; ++i) gi(a[i]), s += a[i];
    	if (s % ((n + 1LL) * n / 2) != 0)
    	{
    		puts("NO");
    		return 0;
    	}
    	s /= ((n + 1LL) * n / 2);
    	int64 all = s, allx = s * (n - 1);
    	for (int i = 1; i <= n; ++i)
    	{
    		if ((s + a[i] - a[i % n + 1]) % n != 0)
    		{
    			puts("NO");
    			return 0;
    		}
    		int64 y = (s + a[i] - a[i % n + 1]) / n;
    		int64 x = s - y;
    		if (y > all || x > allx)
    		{
    			puts("NO");
    			return 0;
    		}
    		all -= y;
    		allx -= x;
    		b[i % n + 1] = y;
    	}
    	if (all || allx) return puts("NO"), 0;
    	int64 cnt = 0, tag = 0;
    	for (int i = 1; i <= n; ++i)
    	{
    		cnt += b[i];
    		tag += cnt;
    		x[i] += tag;
    		if (x[i] > a[i])
    		{
    			puts("NO");
    			return 0;
    		}
    	}
    	for (int i = 1; i <= n; ++i)
    	{
    		cnt -= b[i];
    		tag += cnt;
    		if (b[i]) tag -= n * (b[i]);
    		x[i] += tag;
    		//cerr << x[i] << endl;
    		if (x[i] != a[i])
    		{
    			puts("NO");
    			return 0;
    		}
    	}
    	puts("YES");
    	return 0; 
    }
    

      

    C - Cleaning

    对于每一个非叶节点,所有的覆盖都至少有一个端点在自己的子树里,要么两个都是,要么只有一个,计算一下情况,转移上去,判断即可。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    const int N = 1e5 + 10;
     
    int n, deg[N];
     
    int64 A[N];
     
    VI edge[N];
     
    void dfs(int u, int fa)
    {
    	if (deg[u] <= 1) return;
    	int64 x = 0, cnt = 0, la = 0;
    	for (auto v : edge[u])
    	{
    		if (v == fa) continue;
    		dfs(v, u);
    		x += A[v];
    		la = max(la, A[v]);
    	}
    	cnt = min(x >> 1, x - la);
    	if (x >= A[u] && x <= A[u] + cnt)
    	{
    		int64 c = x - A[u];
    		A[u] -= c;
    	}
    	else
    	{
    		puts("NO");
    		exit(0);
    	}
    }
     
    int main()
    {
    	gi(n);
    	for (int i = 1; i <= n; ++i) gi(A[i]);
    	for (int i = 1; i < n; ++i)
    	{
    		int a, b;
    		gii(a, b);
    		edge[a].pb(b);
    		edge[b].pb(a);
    		++deg[a], ++deg[b];
    	}
    	if (n == 2)
    	{
    		puts(A[1] == A[2] ? "YES" : "NO");
    		return 0;
    	} 
    	int root = 1;
    	for (; deg[root] == 1; ++root);
    	dfs(root, 0);
    	if (!A[root]) puts("YES");
    	else puts("NO");
    }
    

      

    D - Decrementing

    如果不考虑除以gcd的问题,就是sigma(A[i])-n的奇偶来判断胜负,如果有gcd,但如果是奇数,先手肯定必胜,否则看看先手能不能想办法除以2改变奇偶。递归下去交换先后手到一个不能改变的状态就好了。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    const int N = 1e5 + 10;
     
    int n, a[N];
     
    void dfs(int x)
    {
    	long long s = 0;
    	for (int i = 1; i <= n; ++i) 
    		s += a[i] - 1;
    	if (s & 1)
    	{
    		puts(x ? "Second" : "First");
    		return;
    	} 
    	int cnt = 0;
    	for (int i = 1; i <= n; ++i)
    		if (a[i] & 1) ++cnt;
    	for (int i = 1; i <= n; ++i)
    		if (a[i] == 1) cnt = 233;
    	if (cnt != 1)
    	{
    		puts(x ? "First" : "Second");
    		return;
    	}
    	for (int i = 1; i <= n; ++i) 
    		if (a[i] & 1) --a[i];
    	int v = 0;
    	for (int i = 1; i <= n; ++i) v = __gcd(v, a[i]);
    	for (int i = 1; i <= n; ++i) a[i] /= v;
    	dfs(x ^ 1);
    }
     
    int main()
    {
    	gi(n);
    	for (int i = 1; i <= n; ++i) gi(a[i]);
    	dfs(0);
    }
    

      

    E - Rearranging

    我们发现不互质的数相对位置不会改变,那么建出图来,先按从小到大遍历出一个DAG,从大到小跑拓扑序即可。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    const int N = 2010;
     
    int n, a[N], t[N][N], deg[N];
     
    bool vis[N];
     
    VI edge[N];
     
    void dfs(int u)
    {
    	vis[u] = 1;
    	for (int j = 1; j <= n; ++j)
    		if (!vis[j] && t[u][j])
    			edge[u].pb(j), ++deg[j], dfs(j);
    }
     
    priority_queue<int> pq;
     
    int main()
    {
    	gi(n);
    	for (int i = 1; i <= n; ++i) gi(a[i]);
    	sort(a + 1, a + n + 1);
    	for (int i = 1; i <= n; ++i)
    		for (int j = 1; j <= n; ++j)
    			if (__gcd(a[i], a[j]) != 1)
    				t[i][j] = 1;
    	for (int i = 1; i <= n; ++i)
    		if (!vis[i]) dfs(i);
    	for (int i = 1; i <= n; ++i) if (!deg[i]) pq.push(i);
    	while (!pq.empty())
    	{
    		int u = pq.top(); pq.pop();
    		printf("%d ", a[u]);
    		for (auto v : edge[u])
    		{
    			--deg[v];
    			if (!deg[v]) pq.push(v);
    		}
    	}
    	return 0;
    }
    

      

    F - Tree Game

    我们发现只有a[u]>a[v]的(u,v)才能走,否则两个人来回最后还是在原点不能动,所以建出(a[u]>a[v])的图,必败态就是没有出边了,所以对于每个点O(n) dfs一下即可。

    //waz
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
     
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
     
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
     
    int F()
    {
    	char ch;
    	int x, a;
    	while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    	if (ch == '-') ch = getchar(), a = -1;
    	else a = 1;
    	x = ch - '0';
    	while (ch = getchar(), ch >= '0' && ch <= '9')
    		x = (x << 1) + (x << 3) + ch - '0';
    	return a * x;
    }
     
    const int N = 3010;
     
    int n, a[N];
     
    vector<int> edge[N];
     
    bool dfs(int u, int fa)
    {
    	bool ret = 0;
    	for (auto v : edge[u])
    	{
    		if (v == fa) continue;
    		if (a[u] > a[v]) ret |= dfs(v, u) ^ 1;
    	}
    	return ret;
    }
     
    int main()
    {
    	gi(n);
    	for (int i = 1; i <= n; ++i) gi(a[i]);
    	for (int i = 1; i < n; ++i)
    	{
    		int u, v;
    		gii(u, v);
    		edge[u].pb(v);
    		edge[v].pb(u);
    	}
    	for (int i = 1; i <= n; ++i) if (dfs(i, 0)) printf("%d ", i);
    	return 0;
    }
    

      

  • 相关阅读:
    微信小程序 单选按钮 最佳
    微信小程序 单选按钮的实现
    微信小程序 单选框实现
    Java Code To Create Pyramid and Pattern
    Java language
    npm Err! Unexpected end of JSON input while parsing near
    Node.js Express FrameWork Tutorial
    Higher-Order Function Examples
    Create First HTTP Web Server in Node.js: Complete Tutorial
    Node.js NPM Tutorial: Create, Publish, Extend & Manage
  • 原文地址:https://www.cnblogs.com/AnzheWang/p/9643564.html
Copyright © 2011-2022 走看看