zoukankan      html  css  js  c++  java
  • Codeforces Round #717 (Div. 2) A B C 题解

    A Tit for Tat

    题意:给你一个n个数的数组,在k次操作下,每次可以选2个数,一个+1,一个-1,求如何让数组前面的数最小,后面的数最大。最小不能为0.
    思路:模拟,把前面的数-掉都加在最后一个数上

    #include<iostream>
    using namespace std;
    int n,k;
    int s[110];
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d %d",&n,&k);
    		
    		for(int i=1;i<=n;i++) scanf("%d",&s[i]);
    		
    		int j=1;
    		while(k)
    		{
    			if(j==n) break;
    			if(s[j]>k) 
    			{
    				s[j]-=k;
    				s[n]+=k;
    				k=0;
    			}
    			else 
    			{
    			s[n]+=s[j];
    			k-=s[j];
    			s[j]=0;
    			j++;
    			}
    		}
    		
    		for(int i=1;i<=n;i++) printf("%d ",s[i]);
    		printf("
    ");
    	} 
    	return 0; 
    }
    

    B AGAGA XOOORRR

    题意:给你n个数的数组,每次选取两个相邻的元素;然后移除它们,并在它们的位置放置一个整数等于这2个数的异或和,求是否能使数组的所有元素相等。并且至少留下2个元素。
    思路:首先,一定要注意看是相邻
    先发掘一下性质
    1 最后不是2个相等的数就是3个相等的数
    因为4个相等的数等于2个相等的数
    2 相邻的数选
    那么分别暴力枚举2个分割点和1个分割点
    然后取异或和看看想不相等
    查询的时候可以用前缀和来查询 o1
    总体时间复杂度 otn^2 = 6e7

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int N = 20010;
    
    int n, m;
    int g[N];
    int s[N];
    
    int main() 
    {
        int T;
        cin >> T;
        while (T -- ) 
        {
            cin >> n;
            for (int i = 1; i <= n; i ++ ) 
                cin >> g[i];
            
            s[1] = g[1];
            for (int i = 2; i <= n; i ++ ) 
                s[i] = s[i - 1] ^ g[i];
    
            bool flag = false;
            for (int i = 1; i <= n - 1; i ++ ) 
                if (s[i] == (s[n] ^ s[i])) 
                {
                    flag = true;
                    break;
                }
    
            for (int i = 1; i <= n - 1; i ++ ) 
                for (int j = i + 1; j <= n - 1; j ++ ) 
                    if (s[i] == (s[j] ^ s[i]) && s[i] == (s[n] ^ s[j]))  
                    {
                        flag = true;
                        break;
                    }
    
            if (flag) puts("YES");
            else puts("NO");
        }
    
        return 0;
    }
    

    C Baby Ehab Partitions Again

    题意:给你一个n个数的数组,求这个数组是否有2个序列,这2个序列必须包含这所有的n个数,并且每个数只包含一次,顺序随意。
    并且定义,如果第一个子序列中元素的和等于第二个子序列中元素的和,则称这个数组是好的,
    求是否可以通过删除最多一个数的情况下,使得它成为好的数组
    思路:总和是ans的情况下 如果一开始不能表示出来 ans / 2的话 就输出0, 如果可以表示出来的话 就求暴力枚举删除的那一个数a[i],因为最多只删除一个数,然后看如果还是不能表示出来的话 直接输出break,当然前提是ans或者是ans-a[i] 必须是偶数 要不然也直接输出
    能不能表示出来可以用01背包,每次判断选与不选,
    总体时间复杂度 o n^2m = 2e7
    m为数组总和

    #include<bits/stdc++.h>
    #define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
    #define re register int
    #define x first
    #define y second
    typedef long long ll ;
    using namespace std;
    const int N =  1e6 + 10 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    int n , m ;
    int f[N] ;
    int a[N] ;
    int main()
    {
        cin >> n ;
        int ans = 0 ;
        for(int i = 1 ; i <= n ; i ++) 
        {
            cin >> a[i] ;
            ans += a[i] ;
        }
        f[0] = 1 ;
        for(int i = 1 ; i <= n ; i ++)
        {
            for(int j = ans ; j >= a[i] ; j --)
            {
                if(f[j-a[i]] && !f[j])
                {
                    f[j] = true ;
                }
            }
        }
        
        if(!f[ans/2] || ans % 2 != 0) puts("0");
        else 
        {
            for(int k = 1 ; k <= n ; k ++)
            {
                memset(f,0,sizeof f) ;
                f[0] = 1 ;
                for(int i = 1 ; i <= n ; i ++)
                {
                    if(i == k) continue ;
                    for(int j = ans ; j >= 1 ; j --)
                    {
                        if(!f[j] && f[j-a[i]])
                        {
                            f[j] = true ;
                        }
                    }
                }
                if(!f[(ans-a[k]) / 2] || (ans - a[k]) % 2 != 0) 
                {
                    cout << 1 << endl;
                    cout << k << endl;
                    break;
                }
            }
        }
        return 0 ;
    }
    
  • 相关阅读:
    第二次:Ubuntu16.04 安装Docker
    第一次:从今开始玩Linux,Ubuntu16.04
    学习日常
    Vector和ArrayList的异同、Hashtable和HashMap的异同
    如何吃透Python的面向对象(OOP)
    Python基础(下篇)
    Python基础(中篇)
    Python基础(上篇)
    Pycharm安装
    Python的安装与配置
  • 原文地址:https://www.cnblogs.com/yueshehanjiang/p/14687619.html
Copyright © 2011-2022 走看看