Codeforces Round #776 (Div. 3)

A. Deletions of Two Adjacent Letters

Description

已知一个字符串 \(s\) 和一个字符 \(c\)。每次可以从 \(s\) 中删除两个相邻的字符,问是否能够最终剩下一个字符 \(c\)。保证 \(|s|\) 为奇数。

Solution

很明显,\(s\) 的第 \(i\) 个字符 \(s_i\) 能够最终留下的充要条件为 \(i\) 为奇数,即左边有偶数个字符,右边也有偶数个字符。那么我们就可以查找 \(s\) 中的每个 \(c\),判断是否符合条件即可。

Code

#include<bits/stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(0);
	int T;
	string s;
	char c;
	cin>>T;
	while(T--)
	{
		cin>>s>>c;
		bool flag=0;
		for(int i=0;i<s.size();i++)
			if(s[i]==c&&i%2==0&&(s.size()-i-1)%2==0)
			{
				flag=1;
				break;
			}
		if(flag) puts("YES");
		else puts("NO");
	}
	return 0;
}

B. DIV + MOD

Description

定义函数 \(f_a(x)=\lfloor\frac x a\rfloor+x\bmod a\),给出 \(a\)\(l\)\(r\),求 \(f_a(x)\)\([l,r]\) 内的最大值。

Solution

这个函数是由两个量相加而成,因此它在一个区间内的最大值只有下面几种可能:(下面所有的“这个数”均指在区间内使得 \(f_a(x)\) 最大的 \(x\)

  • \(\lfloor\frac x a\rfloor\) 最大,在此前提下使得 \(x\bmod a\) 最大。那么这个数就是 \(r\),很明显它满足上面的两个条件。计算结果为 \((\lfloor\frac r a\rfloor+r\bmod a)\)
  • \(x\bmod a\) 最大,在此前提下使得 \(\lfloor\frac x a\rfloor\) 最大。此时要分两种情况讨论:
    • \(\lfloor\frac l a\rfloor=\lfloor\frac r a\rfloor\),即区间内所有数除以 \(a\) 向下取整的结果都相同,那么这个数还是 \(r\),计算结果依然为 \((\lfloor\frac r a\rfloor+r\bmod a)\)
    • \(\lfloor\frac l a\rfloor<\lfloor\frac r a\rfloor\),那么这个数就是 \((r-1-r\bmod a)\),就是退一步,把 \(\lfloor\frac x a\rfloor\) 减小 \(1\),再让 \(x\bmod a\) 拉满,让它等于 \((a-1)\)。计算结果为 \((\lfloor\frac x a\rfloor+a-2)\)

综上所述,答案就是

\[\begin{cases}\lfloor\frac r a\rfloor+r\bmod a&,\lfloor\frac l a\rfloor=\lfloor\frac r a\rfloor\\\max(\lfloor\frac r a\rfloor+r\bmod a,\lfloor\frac x a\rfloor+a-2)&,\lfloor\frac l a\rfloor<\lfloor\frac r a\rfloor\end{cases} \]

Code

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int l,r,a;
		scanf("%d%d%d",&l,&r,&a);
		if(l/a==r/a) printf("%d\n",r/a+r%a);
		else printf("%d\n",max(r/a+r%a,r/a+a-2));
	}
	return 0;
}

C. Weight of the System of Nested Segments

Description

数轴上有 \(m\) 个点,每个点都有一个坐标 \(x_i\) 和权值 \(w_i\)
定义一个线段序列 \([l_1,r_1],[l_2,r_2],\dots,[l_n,r_n]\) 为嵌套线段系统当 \([l_{i+1},r_{i+1}]\) 被严格嵌套在 \([l_i,r_i]\) 中。现在需要从中选出 \(2n\) 个点,组成 \(n\) 条线段,使其为嵌套线段系统,且所有端点权值和最小。求这个系统。

Solution

事实上,不需要理睬什么嵌套线段系统,只需要从 \(m\) 个点中选出权值最小的 \(2n\) 个,这样它们的和必定最小,然后一首一尾输出原编号即可。

Code

#include<bits/stdc++.h>
using namespace std;
struct point{int x,w,id;}p[200005];
inline bool cmp(const point& a,const point& b)
{
	return a.w<b.w;
}
inline bool cmp2(const point& a,const point& b)
{
	return a.x<b.x;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++) scanf("%d%d",&p[i].x,&p[i].w),p[i].id=i;
		sort(p+1,p+m+1,cmp);//取权值最小的 2n 个点
		sort(p+1,p+n*2+1,cmp2);//将取出的 2n 个点按照坐标排序
		int ans=0;
		for(int i=1;i<=n*2;i++) ans+=p[i].w;
		printf("%d\n",ans);
		for(int i=1;i<=n;i++) printf("%d %d\n",p[i].id,p[n*2-i+1].id);
		puts("");
	}
	return 0;
}
posted @ 2022-03-11 12:56  ryanright  阅读(106)  评论(0)    收藏  举报