Codeforces Round #717 (Div. 2)A-B详解_xooo3-程序员宅基地

技术标签: 算法  动态规划  

题目链接:https://codeforces.com/contest/1516

A.Tit for Tat


题意:给定一个数组,然后再给定n和k。你可以执行操作如下:
给任意两个不同的元素(下标不同)一个加上1,一个减掉1
最多执行k次这样的操作,并且序列中不能出现负数。请你给出一个字典序最小的数组。

字典序:参考字符串的字典序比较。

思路
1.既然要字典序最小,那么 要让前面的数尽可能的小,那么我们就尽可能的减掉当前最前面的数,给最后面的数加1。如果到0了,就下一个数。当然,k次用完了就退出了。然后要保持没有负数。


AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=220;
int n,k;
int a[N];
int t;
int main()
{
    
	cin>>t;
	while(t--)
	{
    
		cin>>n>>k;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<=n;i++)
		{
    
			if(a[i]==0||i==n) continue;
			while(a[i]>0&&k>0)
			{
    
				a[i]--;
				a[n]++;k--;
			}
		}
		for(int i=1;i<=n;i++) cout<<a[i]<<" ";
		cout<<endl;
	}
	return 0;
}

B–AGAGA XOOORRR

题意:给你一个序列,你可以执行以下操作:把*相邻相邻相相邻的两个数异或(^),然后生成新的数。问你是否能通过一系列这样的操作,使得序列中满足元素都相等,且元素要满足大于等于2

关于异或

  1. (X^Y) ^Z == X^(Y ^Z)
  2. X^X=0 , X^0=X, X^X ^X=X.

思路重点:

(结论1)我们从末态出发,即最终的状态是序列都是同一个数。那么这个序列的长度要么是2,要么是3。

证明:因为,X^X=0,比如当前长度为4,序列为【X,X,X,X】,我们可以通过把后两个X ^X=0,序列就变成【X,X,0】,然后才把X ^ 0=X,于是,序列就变成了【X,X】 。奇数的情况同理。

2.当序列为偶数的那种情况,我们可以发现,如果序列可以构成相同,即最终状态为偶数个X,那么我们把这么多个X一起异或,即【X^X ^X ^X…】,那么最终一定是0,
所以当最终异或和为0的序列一定可以


讨论最终长度为奇数的情况
3,当序列为奇数的情况时,我们可以发现,序列的异或和为一个数Y(n为奇数,即n=2*k+1,k对的偶数异或都为0),所有最终为一堆0和一个数Y,如果序列可以满足,那么最终的数就是Y。

4.又因为最终需要大于等于2个数,相等所以我们只需要判断这里序列是否能够化成长度大于等于2且元素都相等的序列,即是否能找到2个及以上的Y。

实现

前缀异或 ans[i]=ans[i-1]^a[i]。


AC代码:(注释)

#include<bits/stdc++.h>
using namespace std;
int t,n;
int a[2100];
int main()
{
    
   
    cin>>t;
    while(t--)
    {
    
        cin>>n;
        for(int i=0;i<n;i++)
        {
    
            cin>>a[i];
        }
        int ans = 0;
        for(int i=0;i<n;i++)
        {
    
            ans = ans^a[i]; 
        }
        if(ans == 0)
        {
    
            cout<<"YES\n";continue;
        }else
        {
    
            int temp = 0;
            int count = 0;
            for(int i=0;i<n;i++)
            {
    
                temp = temp^a[i];//异或前缀 
                if(temp == ans)
                {
    
                    count++; 
                    temp = 0;//满足的时候让他归0,可以理解把奇数凑成偶数,或者当前区间满足,找下个区间的时候从初始态开始异或。 
                }
            }//cnt就是记录最后剩下的数是不是大于2,已知最后一个数是Y,那么最少在前面再找一个Y即可。 
            if(temp == 0 && count>1 ) cout<<"YES\n";
            else cout<<"NO\n";
        }
    }
    

    return 0;
}

解法二

同样的,既然要使最终元素都相同。
那么,一定是若干个区间生成相同的数,组成的序列。
例如一个序列为【A,B,C,D,E,F】
那么在异或计算下可以是【A,B】=X,【C,D,E】=X,【F】=X。
再根据上面所讲,

要么分成2个区间,要么分成3个区间

异或前缀的运用

==类似于前缀和求区间【L,R】的和,区间【L,R】的异或和也可以通过
f[R]^f[L-1]。求得。

区间[L,R]异或和为 f[R]^f[L-1]

所以,我们把前缀异或和数组处理好后,直接枚举区间不就行了。

枚举2个区间1个for,枚举3个区间2个for,我这里一起处理了

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e3+10;
map<ll,ll> mp;
ll a[N];
ll ans[N];
ll ans2[N];
int t;
int n;
void solve()
{
    
	if(n==1)
	{
    
		cout<<"NO"<<endl;return;
	}
	for(int i=1;i<=n;i++)
	{
    
		for(int j=i;j<=n;j++)
		{
    
			if(i==j&&ans[i]==(ans[n]^ans[i])) // [1,i] 和[i+1,n] 这两个区间。 
		{
    
			cout<<"YES"<<endl;return;
		}
		if(i!=j&&ans[i]==(ans[n]^ans[j])&&(ans[i]==(ans[i]^ans[j]))) //[1,i] 和 [i+1,j] 和 [j+1,n] 3个区间 
			{
    
				cout<<"YES"<<endl;
				return ;
			 }  
		}
	}
	
	cout<<"NO"<<endl;
	return ;
	 
}
int main()
{
    
	cin>>t;
	while(t--)
	{
    
		scanf("%d",&n);
		ll res=0;
		for(int i=1;i<=n;i++)
		{
    
		scanf("%lld",&a[i]);
		res=res*a[i]; 
		ans[i] = ans[i-1] ^ a[i];
		}
		solve();
	
	}
	return 0;
}

C代码

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int f[N];
int a[N];
int t,n;
int sum;
bool check()
{
    
	f[0]=1;
	for(int i=1;i<=n;i++)
	{
    
		for(int j=N;j>=0;j--)
		{
    
			f[j+a[i]]+=f[j];
		}
	}
//	printf("f[sum/2]===%d \n",f[sum/2]);
	if(f[sum/2]) return false;
	return true;
}
int main()
{
    
	
		cin>>n;
		//int sum=0;
		for(int i=1;i<=n;i++)
		{
    
			cin>>a[i];
		}
		int k=a[1];
		for(int i=2;i<=n;i++)
		{
    
			k=__gcd(k,a[i]);
		}
		for(int i=1;i<=n;i++)
		{
    
			a[i]/=k;sum+=a[i];
		}
	//	printf("k===%d \n",k);
		if(sum%2==1)
		{
    
			cout<<"0"<<endl;return 0;
		}
		else
		{
    
			int st;//下标
		//	printf("st===%d \n",st);
			for(int i=1;i<=n;i++)
			{
    
				if(a[i]%2==1)
				{
    
					st=i;
				}
			}
		//	printf("st===%d \n",st);
	//		printf("chek=== %d\n",check());
			if(check()==1) 
			{
    
				cout<<"0"<<endl;
			}
			else
			{
    
				cout<<"1"<<endl;
				cout<<st<<endl;
			}
		}
		return 0;
	
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_51670469/article/details/116034244

智能推荐

2023.8DataWhale_cv夏令营第三期笔记_逻辑回归需要训练很多轮么-程序员宅基地

文章浏览阅读257次。使用官方提供的脑PET数据集,构建逻辑回归模型来进行脑PET图像的疾病预测,数据集被分为两类,分别为轻度认知障碍(MCI)患者的脑部影像数据和健康人(NC)的脑部影像数据,图像数据格式为nii,因此本赛题可抽象为一个二分类问题。nii是一种常用的医学图像数据格式,主要用于存储和交换神经影像数据。以下是一些主要特点:1.主要用于存储3D(三维)医学图像数据,如MRI(磁共振成像)和CT(计算机断层扫描)图像。2.支持多种数据类型,使得其可以支持不同类型的数据处理和分析。_逻辑回归需要训练很多轮么

通用指南-营销和设计中的增强现实(AR)-程序员宅基地

文章浏览阅读1.2k次,点赞31次,收藏26次。增强现实通常被视为一个利基领域。然而,在过去的两年里,它已经到了一个成熟的阶段,应该在一般的营销堆栈中进行考虑。正如我们所看到的,这个市场是巨大的,而且随着主要参与者向这项技术投入大量投资,它只会继续增长。从苹果到Meta,大公司都相信身临其境的未来,而想要获得成功的营销人员和创意人员也加入了进来。本文第三章,最佳设计实践除了深入讨论AR设计的原则外,还全面推荐了AI设计工具。旨在帮助读者的AI作品脱颖而出。

linux c 网络编程_usage: ./tcp_client hostname-程序员宅基地

文章浏览阅读473次。OSI七层网络模型由下至上为1至7层,分别为:物理层(Physical layer),数据链路层(Data link layer),网络层(Network layer),传输层(Transport layer),会话层(Session layer),表示层(Presentation layer),应用层(Application layer)。1.1 应用层,很简单,就是应用程序。这一层负责_usage: ./tcp_client hostname

Nexus3配置yum代理 pypi代理和npm代理(三合一)_maximum component age-程序员宅基地

文章浏览阅读2.8k次。环境准备安装 maven 安装 java 环境[root@cicd-nexus ~]# wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz[root@cicd-nexus ~]# tar xf apache-maven-3.6.3-bin.tar.gz -C /usr/local/[root@cicd-nexus ~]# tar xf _maximum component age

使用js-xlsx handsontable 分批次导入Excel数据(兼容ie9)_js 导excel 分批写入-程序员宅基地

文章浏览阅读1.6k次。使用js-xlsx handsontable 可以把本地excel 解析到网页上,然后分批次传入后台。在chrome 下 可以参考 https://github.com/SheetJS/js-xlsx 【Browser file upload form element】但需要使用FileReader api 这个只有ie10 才开始支持。兼容ie9 ,ie9需要通过flash 来支持..._js 导excel 分批写入

wxWidgets 自绘按钮(图片+文字)_wxwidgets 中文按钮-程序员宅基地

文章浏览阅读2.5k次。在wxWidgets中,想要通过其本身的控件来实现图片+文件的按钮,貌似不太容易做到。但是可以通过重载wxControl来自绘图片+文件按钮。下面给出的是已经封装好的按钮类:wxBitmapButtonEx.h#ifndef _BITMAP_BUTTON_EX_H#define _BITMAP_BUTTON_EX_H#include "wx/wx.h"enum eBitm_wxwidgets 中文按钮

随便推点

invalidate()和postInvalidate()的区别_postinvalidate和invalidate的区别-程序员宅基地

文章浏览阅读847次。invalidate()与postInvalidate()都用于刷新View,主要区别是invalidate()在主线程中调用,若在子线程中使用需要配合handler;而postInvalidate()可在子线程中直接调用。postInvalidate它是向主线程发送个Message,然后handleMessage时,调用了invalidate()函数。(系统帮我们 写好了 Handle..._postinvalidate和invalidate的区别

计算机表格 求差,Excel表格中求差函数公式怎么用-程序员宅基地

文章浏览阅读9.1k次。excel数据进行分类汇总的步骤在做分类汇总前,我们需要对数据先进行排序,否则分类汇总无法进行。得到排序后的表格。点击上方工具栏中的“数据”→“分类汇总”。在弹出的对话框中选择“分类字段”→“汇总方式”→“决定汇总项”。点击确定出现数据汇总结果。Excel表格中求差函数公式使用的方法第一步:打开Excel表格,单击第一排,第三个“单元格”,也就是C1,在C1中输入“=A1-B1”;第二步:这个公式..._表格求差公式

Linux下OpenCV的安装与测试成功教程(解决E: 无法定位软件包 libjasper-dev、无法找到directory `opencv.pc‘、fatal error:“highgui.h“)_无法定位软件包 libgazebo-dev-程序员宅基地

文章浏览阅读1.5w次,点赞49次,收藏169次。前言好激动,断断续续装了两三天才装上,踩了好多坑。这里把成功安装的步骤详细写下来,如果有小伙伴需要,可以尝试一下,但我不能保证你也可以装好。首先说一下我的各个版本(不谈版本的安装教程都是耍流氓!)是用虚拟机软件:VirtualBOX6.1.30系统版本:ubuntu-20.04.3-desktop-amd64(最小安装模式,中文)OpenCV版本:4.5.5安装时间:2022.2.11下面是步骤1、进入OpenCV的官方下载地址Releases - OpenCV,下载So_无法定位软件包 libgazebo-dev

红帽子粉帽子绿帽子II(递归,递推)-程序员宅基地

文章浏览阅读320次,点赞6次,收藏10次。/是上一个的进化版,相邻的可以一样但是不能都是绿色,注意条件;~~~//仅当笔者个人备忘录使用。

解决Install Intel x86 Emulator Accelerator (HAXM installer) (revision: 7.6.5)“ failed问题-程序员宅基地

文章浏览阅读6.7k次。由于Install Intel x86 Emulator Accelerator (HAXM installer) (revision: 7.6.5)安装失败,导致我的安卓虚拟机无法启动。解决办法有一下几种:1.开机进入BIOS打开Virtual虚拟化功能,然后进入Androidstudio 的SDK manager里面安装HAXM2.关闭系统中的Hyper-v,进入控制面板的程序和功能,将Hyper-v去选即可。3.如果前面的方法都不行,那么建议你重新下载AndroidStudio最新版进行安装_intel x86 emulator

PowerBuilder的语言基础-程序员宅基地

文章浏览阅读1.1w次,点赞2次,收藏15次。 每一种语言都有一组基本的语法约定,POWERBUILDER也不例外。 (1)断行、续行与多条语句 通常情况下,powerbuilder的一条语句是写到一行上的,该条语句在书写完毕之后,按键转到下一行,开始写下一句的内容。也就是说,在PowerBuilder中,使用键作为一行的结束。在PowerBuilder语句比较长的情况下,为了方便阅读,可以使用续行符号把一条语句写到几_powerbuilder