IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Codeforces Round #741 div.2 A-D题解 -> 正文阅读

[数据结构与算法]Codeforces Round #741 div.2 A-D题解

视频讲解:TBD

A. The Miracle and the Sleeper

题目大意

给定两个正整数 l , r ? ( 1 ≤ l ≤ r ≤ 1 0 9 ) l,r~(1 \leq l \leq r \leq 10^9) l,r?(1lr109) ,求满足 r ≥ a ≥ b ≥ l r \ge a \ge b \ge l rabl 的最大的 $a \mod{b} $ 。

题解

l l l 足够小,那么 a a a 应该取 r r r b b b 应该取 ? r + 1 2 ? \lfloor \frac{r+1}{2} \rfloor ?2r+1?? ,答案为 ? r ? 1 2 ? \lfloor \frac{r-1}{2} \rfloor ?2r?1??
l l l 较大,那么 a = r , b = l a=r,b=l a=r,b=l ,答案为 r m o d ?? l r\mod{l} rmodl
分界点为 ? r + 1 2 ? \lfloor \frac{r+1}{2} \rfloor ?2r+1??

参考代码

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int T,l,r;
	cin>>T;
	while(T--)
	{
		cin>>l>>r;
		if(l<=(r+1)/2)
			cout<<(r-1)/2<<endl;
		else
			cout<<r-l<<endl;
	}
}

B. Scenes From a Memory

题目大意

给定一个十进制下不包含 0 0 0 的整数 n ( 1 ≤ n < 1 0 50 ) n(1 \le n < 10^{50}) n(1n<1050) ,删除最多的数字,使其变为非素数。

给定数据保证有解,若有多组解则输出任意一种即可。

题解

若包含 1 , 4 , 6 , 8 , 9 1,4,6,8,9 1,4,6,8,9 之一,则直接输出一位数即可。
若包含 2 , 5 2,5 2,5 之一且不为首位,则直接输出首位与 2 2 2 5 5 5 即可。
若包含两个 3 , 7 3,7 3,7 ,则直接输出 33 33 33 77 77 77 即可。
剩余只有 37 , 73 , 237 , 273 , 537 , 573 37,73,237,273,537,573 37,73,237,273,537,573 这几种情况。由于保证必定有解,因此不存在 37 , 73 37,73 37,73 这两种无解情况。对于剩余四种情况,显然 27 27 27 57 57 57 合法。

因此,答案必定为二位数,可以通过上述方式分类讨论,也可以直接枚举得到。

参考代码

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int T,sum[15],pos[15],i,j,k,flag;
	char s[55];
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&k);
		scanf("%s",&s);
		memset(sum,0,sizeof(sum));
		for(i=0;i<k;i++)
		{
			sum[s[i]-'0']++;
			pos[s[i]-'0']=i;
		}
		if(sum[1])
			printf("1\n1\n");
		else if(sum[4])
			printf("1\n4\n");
		else if(sum[6])
			printf("1\n6\n");
		else if(sum[8])
			printf("1\n8\n");
		else if(sum[9])
			printf("1\n9\n");
		else if(sum[2]&&pos[2]!=0)
			printf("2\n%c2\n",s[0]);
		else if(sum[5]&&pos[5]!=0)
			printf("2\n%c5\n",s[0]);
		else if(sum[3]>1)
			printf("2\n33\n");
		else if(sum[7]>1)
			printf("2\n77\n");
		else
		{
			flag=1;
			for(i=0;i<k&&flag;i++)
			{
				for(j=i+1;j<k;j++)
				{
					if((s[i]-'0'+s[j]-'0')%3==0)
					{
						printf("2\n%c%c\n",s[i],s[j]);
						flag=0;
						break;
					}
				}
			}
		}
	}
}

C. Rings

题目大意

有一个长度为 n ? ( 2 ≤ n ≤ 2 ? 1 0 4 ) n~(2 \leq n \leq 2\cdot 10^4) n?(2n2?104) 仅由01构成的字符串 s s s

定义函数 f f f 表示将字符串视为二进制数后再转为十进制数的结果,例如 f ( 001010 ) = 10 f(001010)=10 f(001010)=10

你需要找到满足以下条件的两对整数 ( l 1 , r 1 ) , ( l 2 , r 2 ) (l_1,r_1),(l_2,r_2) (l1?,r1?),(l2?,r2?)

  • 1 ≤ l 1 ≤ n , 1 ≤ r 1 ≤ n , r 1 ? l 1 + 1 ≥ ? n 2 ? 1 \leq l_1 \leq n,1 \leq r_1 \leq n,r_1-l_1+1\geq \lfloor \frac{n}{2} \rfloor 1l1?n,1r1?n,r1??l1?+1?2n??
  • 1 ≤ l 2 ≤ n , 1 ≤ r 2 ≤ n , r 2 ? l 2 + 1 ≥ ? n 2 ? 1 \leq l_2 \leq n,1 \leq r_2 \leq n,r_2-l_2+1\geq \lfloor \frac{n}{2} \rfloor 1l2?n,1r2?n,r2??l2?+1?2n??
  • 存在非负整数 k k k ,满足 f ( s [ l 1 : r 1 ] ) = f ( s [ l 2 : r 2 ] ) ? k f(s[l_1:r_1])=f(s[l_2:r_2])\cdot k f(s[l1?:r1?])=f(s[l2?:r2?])?k

题解

由于是二进制下截取子串,因此考虑 k = 2 k=2 k=2 的情况。
? i ∈ [ ? n 2 ? + 1 , n ] , s [ i ] = 0 \exist i\in[\lfloor \frac{n}{2} \rfloor+1,n],s[i]=0 ?i[?2n??+1,n],s[i]=0 则存在合法情况 ( l 1 , r 1 ) = ( 1 , i ) , ( l 2 , r 2 ) = ( 1 , i ? 1 ) , k = 2 (l_1,r_1)=(1,i),(l_2,r_2)=(1,i-1),k=2 (l1?,r1?)=(1,i),(l2?,r2?)=(1,i?1),k=2

当不存在上述 i i i 时,则表示 s s s 后半段全为 1 1 1
s [ ? n 2 ? ] = 0 s[\lfloor \frac{n}{2} \rfloor]=0 s[?2n??]=0 ,则存在合法情况 ( l 1 , r 1 ) = ( ? n 2 ? , n ) , ( l 2 , r 2 ) = ( ? n 2 ? + 1 , n ) , k = 1 (l_1,r_1)=(\lfloor \frac{n}{2} \rfloor,n),(l_2,r_2)=(\lfloor \frac{n}{2} \rfloor+1,n),k=1 (l1?,r1?)=(?2n??,n),(l2?,r2?)=(?2n??+1,n),k=1
s [ ? n 2 ? ] = 1 s[\lfloor \frac{n}{2} \rfloor]=1 s[?2n??]=1 ,则存在合法情况 ( l 1 , r 1 ) = ( ? n 2 ? , n ? 1 ) , ( l 2 , r 2 ) = ( ? n 2 ? + 1 , n ) , k = 1 (l_1,r_1)=(\lfloor \frac{n}{2} \rfloor,n-1),(l_2,r_2)=(\lfloor \frac{n}{2} \rfloor+1,n),k=1 (l1?,r1?)=(?2n??,n?1),(l2?,r2?)=(?2n??+1,n),k=1

参考代码

#include<bits/stdc++.h>
using namespace std;

const int MAXN=20020;
char s[MAXN];

int main()
{
	int T,n,flag,i;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		scanf("%s",s+1);
		flag=0;
		for(i=n/2+1;i<=n;i++)
		{
			if(s[i]=='0')
			{
				printf("%d %d %d %d\n",1,i,1,i-1);
				flag=1;
				break;
			}
		}
		if(!flag)
		{
			if(s[n/2]=='0')
				printf("%d %d %d %d\n",n/2,n,n/2+1,n);
			else
				printf("%d %d %d %d\n",n/2,n-1,n/2+1,n);
		}
	}
}

D1+D2. Two Hundred Twenty One

题目大意

有一个长度为 n ? ( 1 ≤ n ≤ 3 ? 1 0 5 ) n~(1 \leq n \leq 3 \cdot 10^5) n?(1n3?105) 的仅由±组成的字符串 s s s ,其中+可以视为 1 1 1 ,-可以视为 ? 1 -1 ?1 。字符串合法的条件是奇数位之和等于偶数位之和,即 ∑ i = 1 n ( ? 1 ) i ? 1 s i = 0 \sum_{i=1}^n(-1)^{i-1}s_i=0 i=1n?(?1)i?1si?=0

q ( 1 ≤ q ≤ 3 ? 1 0 5 ) q(1 \leq q \leq 3 \cdot 10^5) q(1q3?105) 次询问,每次给定区间 [ l , r ] ? ( 1 ≤ l ≤ r ≤ n ) [l,r]~(1 \leq l \leq r \leq n) [l,r]?(1lrn) ,求最少需要删除多少字符,才能使得子串 s [ l , r ] s[l,r] s[l,r] 合法。

对于Easy Version,只需输出删除数量。
对于Hard Version,还需输出删除方案。

题解

定义字符串 s s s 的权值为 ∑ i = 1 ∣ s ∣ ( ? 1 ) i ? 1 s i \sum_{i=1}^{|s|}(-1)^{i-1}s_i i=1s?(?1)i?1si?
s u m i sum_i sumi? 表示子串 s [ 1 , i ] s[1,i] s[1,i] 的权值。
在子串 s [ l , r ] s[l,r] s[l,r] 中删除字符 s i s_i si? ,则表示对 s [ i + 1 , r ] s[i+1,r] s[i+1,r] 部分的子串权值取相反数。
由于 s u m i sum_i sumi? 在整数上连续,因此不妨设 f ( i ) f(i) f(i) 表示 s [ l , r ] s[l,r] s[l,r] 删除 s i s_i si? 后的权值:
f ( i ) = s u m i ? 1 ? s u m l ? 1 ? ( s u m r ? s u m i ) f(i)=sum_{i-1}-sum_{l-1}-(sum_r-sum_i) f(i)=sumi?1??suml?1??(sumr??sumi?)
易得
f ( i + 1 ) ? f ( i ) = s u m i + 1 ? s u m i ? 1 f(i+1)-f(i)=sum_{i+1}-sum_{i-1} f(i+1)?f(i)=sumi+1??sumi?1?

因此 f ( i + 1 ) ? f ( i ) f(i+1)-f(i) f(i+1)?f(i) 的值必定为 0 0 0 ± 2 \pm 2 ±2

f ( l ) = ? s u m r + s u m l f(l)=-sum_r+sum_l f(l)=?sumr?+suml?

f ( r ) = s u m r ? 1 ? s u m l ? 1 = ? f ( l ) ? s r + s l f(r)=sum_{r-1}-sum_{l-1}=-f(l)-s_r+s_l f(r)=sumr?1??suml?1?=?f(l)?sr?+sl?

易得 f ( r ) + s r f(r)+s_r f(r)+sr? f ( l ) ? s l f(l)-s_l f(l)?sl? 互为相反数。
f ( r ) ≥ 2 f(r)\geq 2 f(r)2 f ( l ) ≤ 0 f(l)\leq 0 f(l)0
f ( r ) ≤ ? 2 f(r)\leq -2 f(r)?2 f ( l ) ≥ 0 f(l)\geq 0 f(l)0
f ( r ) = 0 f(r)=0 f(r)=0 则直接找到解。
f ( r ) = ± 1 f(r)=\pm 1 f(r)=±1 则无解。
因此

  • f ( r ) f(r) f(r) 为偶数时,由于连续函数性质,必定存在 f ( i ) = 0 f(i)=0 f(i)=0
  • f ( r ) f(r) f(r) 为奇数时,无解。

对于Easy version,

  • s u m r ? s u m l ? 1 = 0 sum_r-sum_{l-1}=0 sumr??suml?1?=0 则不用删除字符。
  • s u m r ? s u m l ? 1 sum_r-sum_{l-1} sumr??suml?1? 为奇数,根据 f ( i ) f(i) f(i) 的性质,必定存在 i i i 满足 s u m r ? s u m i = s u m i ? 1 ? s u m l ? 1 sum_r-sum_i=sum_{i-1}-sum_{l-1} sumr??sumi?=sumi?1??suml?1? ,因此删除一个字符。
  • s u m r ? s u m l ? 1 sum_r-sum_{l-1} sumr??suml?1? 为偶数,则删除任意一个字符(例如 s l s_l sl? )后即可转化为前一种问题。因此删除两个字符。

对于Hard version,
我们需要寻找满足 s u m r ? s u m i = s u m i ? 1 ? s u m l ? 1 sum_r-sum_i=sum_{i-1}-sum_{l-1} sumr??sumi?=sumi?1??suml?1? i i i ,将式子变化为:
s u m r + s u m l ? 1 = s u m i + s u m i ? 1 sum_r+sum_{l-1}=sum_i+sum_{i-1} sumr?+suml?1?=sumi?+sumi?1?

因此可以将每个 i i i 放入 s u m i + s u m i ? 1 sum_i+sum_{i-1} sumi?+sumi?1? 的桶中统计,由于必定有解,因此查找时直接在对应桶中二分查找 [ l , r ] [l,r] [l,r] 区间内的 i i i 即可。

注意 s u m i + s u m i ? 1 sum_i+sum_{i-1} sumi?+sumi?1? 可能为负,因此需要加偏移量 B = 2 n B=2n B=2n

参考代码

#include<bits/stdc++.h>
using namespace std;

const int MAXN=300300;
const int B=MAXN<<1;
char s[MAXN];
int sum[MAXN];
vector<int> vec[MAXN<<2];

int main()
{
	int T,n,q,i,l,r,dif,x,id;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&q);
		scanf("%s",s+1);
		for(i=B-2*n;i<=B+2*n;i++)
			vec[i].clear();
		for(i=1;i<=n;i++)
		{
			if(i&1)
				sum[i]=sum[i-1]+(s[i]=='+'?1:-1);
			else
				sum[i]=sum[i-1]-(s[i]=='+'?1:-1);
			vec[sum[i]+sum[i-1]+B].push_back(i);
		}
		while(q--)
		{
			scanf("%d%d",&l,&r);
			dif=sum[r]-sum[l-1];
			if(dif==0)
				printf("0\n");
			else
			{
				if(dif%2)
					printf("1\n");
				else
				{
					printf("2\n");
					printf("%d ",l);
					l++;
				}
				x=sum[r]+sum[l-1]+B;
				id=lower_bound(vec[x].begin(),vec[x].end(),l)-vec[x].begin();
				printf("%d\n",vec[x][id]);
			}
		}
	}
}

E. Rescue Niwen!

题目大意

TBD

题解

参考代码


F. Tubular Bells

题目大意

TBD

题解

参考代码


  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-28 09:36:03  更:2021-08-28 09:37:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 8:31:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计