Codeforces Round 908 (Div. 2)

CF1894 总结

T1

题目大意:

A,B两人玩游戏,游戏规则如下:
整场游戏有多轮,每轮游戏先胜 X 局的人获胜,每场游戏先胜 Y 局的人获胜。

你在场边观看了比赛,但是你忘记了 xy ,只记得总共比了 1n20 局,和每局获胜的人,请判断谁获胜了。如果A获胜,输出 A ,如果B获胜,输出 B ,如果都有可能,输出 ?

翻自洛谷CF1894A

分析:

不难看出最后一局胜利的就是胜利的人。
提示:若已经决出胜负,则不会继续进行比赛。

code:

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

int main ()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,ans=0;
		cin>>n;
		string s;
		cin>>s;
		cout<<s[n-1]<<'\n';
	}
    return 0;
}

T2

题意:

给定一个数组 a1,a2,...,an。你需要找到一个数组 b1, b2, ..., bn,其中包含数字 1,2,3,使得以下三个条件中恰好有两个条件被满足:

  • 存在 1i,jn,使得 ai=aj,bi=1,bj=2
  • 存在 1i,jn,使得 ai=aj,bi=1,bj=3
  • 存在 1i,jn,使得 ai=aj,bi=2,bj=3

如果不存在这样的数组 b,请报告不可以。

翻自洛谷CF1894B

分析:

三个条件的前提条件都是有两个数相等,也就是说我们只要处理相等的数。不相等的数全部置为1。再来考虑相等的数,如果几个数相等,把它们分别置为1,2,3,则必定满足三个条件。所以只能有两个数如1,3,使他满足一个条件,再找另一组相同的数,使他满足另一条件。
具体只需一个桶统计数的个数,第一组个数大于1的数置为2,第二组个数大于1的数置为3,其他数置为1。
如: 1 2 3 4 2 1 4 3 4 2 1
输出:2 2 1 1 1 1 1 1 1 1 1

code:

#include <bits/stdc++.h>
using namespace std;
const int N=105;
int a[N],b[N],c[N];
int main ()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		int x=0,y=0,x1,x2,st=0;
		cin>>n;
		for(int i=1;i<=100;i++) b[i]=0,c[i]=1;
		for(int i=1;i<=n;i++) cin>>a[i],b[a[i]]++;
		for(int i=1;i<=100;i++) if(b[i]>1) x++;
		if(x<2) st=1;
		if(st) 
		{
			cout<<-1<<'\n';
			continue;
		}
		y=2;
		for(int i=1;i<=n;i++)
		{
			if(b[a[i]]>1&&y<4) cout<<y<<" ",y++,b[a[i]]=0;
			else cout<<1<<" "; 
		}
		cout<<'\n';
	}
    return 0;
}

T3

题意:

给定长度为 n 的数列 a,定义一次轮换为将 a1,a2,,an 变为 a2,a3,,an,a1

定义一次操作为,先选择一个满足 ax=x 的数 x,然后对数列做 x 次轮换。

再给定 k 与数列 b,求是否存在一个初始序列 a,使得其能经过恰好 k 次合法的操作变为 b

n2×105,k109

翻自洛谷CF1893A

分析:

本题最最最关键一点是 ax 轮换 x 次后,都会变成 an
从这入手,倒推的话我们每次只需考虑 anan 一定是从 ax 推过来的.如:7 2 1 一定是由 1 7 2 推过来的。
则我们只需考虑如果 ann,进行还原操作,把数组向右移动 an 。如果 an>n,则说明无法返回,输出 No
还原只需一个变量 move,循环不一定用 k 次,因为只有最多 n 个状态。

code:

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int a[N];
int main ()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,k,move=0,st=1;
		cin>>n>>k;
		for(int i=1;i<=n;i++) cin>>a[i];
		if(k>n) k=n;
		for(int i=1;i<=k;i++)
		{
			if(a[n-move]>n) 
			{
				cout<<"No"<<'\n';
				st=0;
				break;
			}
			else
			{
				move+=a[n-move];
				if(move>=n) move-=n;
			}
		}
		if(st) cout<<"Yes"<<'\n';
	}
    return 0;
}

T4

题意:

给定两个序列 a,b,将 b 中所有元素以任意顺序在任意位置插入 a 中,使得形成的新序列 c 的最长上升子序列最短,输出你的序列 c

翻自洛谷CF1893B

分析:

a 序列的顺序是不变的,也就是说 LIS(c) 的大小至少为 LIS(a)。考虑是否一定能使 LIS(c)=LIS(a),显然是可以的。首先将 b 序列排序,LIS(b)=0,然后,a,b 中元素,哪个大就把哪个插入到 c 中,使用两个指针,贪心更新 c

code:

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int a[N];
int main ()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n,k,move=0,st=1;
		cin>>n>>k;
		for(int i=1;i<=n;i++) cin>>a[i];
		if(k>n) k=n;
		for(int i=1;i<=k;i++)
		{
			if(a[n-move]>n) 
			{
				cout<<"No"<<'\n';
				st=0;
				break;
			}
			else
			{
				move+=a[n-move];
				if(move>=n) move-=n;
			}
		}
		if(st) cout<<"Yes"<<'\n';
	}
    return 0;
}

T5

题意:

注:下文中的 multiset 均为可重集。

我们定义一个大小为 len 的 multiset 的不优美度为数 len 在这个 multiset 里的出现次数。

给你 m 个 multiset,第 i 个 multiset 包含 ni 个不同的元素,具体的:这个 multiset 中含有 ci,1ai,1ci,2ai,2ci,niai,ni。保证 ai,1<ai,2<<ai,ni。同时给你 l1,l2,,lmr1,r2,,rm,其中 1lirici,1++ci,ni

我们按照如下操作创建一个 multiset X ,最初 X 为空。然后,对于 1m 的每一个数 i,执行下面的操作:

1.选择一个数 vi 使得 liviri

2.从第 i 个 multiset 里选择任意 vi 个数并把它们加入 X 。

你的任务是选择 v1,,vm ,使得 multiset X 的不优美度最小。

多测,1t104 , 1m1051ni105,1lirici,1++ci,ni10171ai,1<<ai,ni10171ci,j1012m 的总和以及所有数据里的 ni 的总和不超过 105

翻自洛谷CF1893C

没看懂题意 qwq。

posted @   zhouruoheng  阅读(39)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示