Codeforces Round #807 (Div. 2)补题

这篇博客介绍了如何使用C++解决两个Codeforces上的编程问题。第一个问题是关于字符串复制的,通过定义新的longlong类型并使用特定的数据结构和算法来处理字符串在不同区间复制的情况。第二个问题涉及到灯泡的排列,主要考察了字符串比较和连续块匹配的算法。博客中提供了详细的代码实现和解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C. Mark and His Unfinished Essay

https://codeforces.com/contest/1705/problem/C

会卡long long,下面解法62ms过的,还是参考了dalao们的思路,发现这个思路是最最最清晰的;

学会一种新的定义long long 的方法:定义#define int long long 然后signed main()

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100
#define int long long 
#define FA ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
int n,m,c,q;
int l[N],r[N],lc[N],rc[N];

//l[],r[] is 复制的区间
//lc[],rc[] is 复制完的新位置
 
signed main()
{
	int t;
	FA;
	cin>>t;
	
	while(t--)
	{
		cin>>n>>c>>q;
		string s;
		cin>>s;
		int len=s.size();
		for(int i=1;i<=c;i++)
		{//第i次的复制区间,总共C次复制,c个区间 
			cin>>l[i]>>r[i];
			int newlen=r[i]-l[i]+1;
			//更新复制到的区间位置 
			lc[i]=len+1;//在现在尾位置后面粘贴 
			rc[i]=lc[i]+newlen-1;
			len+=newlen;//更新现在的串长度 
		}
		while(q--)
		{
			int k;
			cin>>k;
			//回去找原位置的字符
			//从最后一个区间开始向前找 
			for(int i=c;i>=1;i--)
			{//现在看看k是在哪个区间里,用该区间的l[],r[],lc[],rc[]算原位置 
				if(lc[i]<=k && k<=rc[i])
				{
					k=k-lc[i]+l[i];
				//k-lc[该区间]==k数在该区间的位序
				//l[i]为现在这个区间对于原区列的首位置
				//加上l[i]就是该数字在原区间的序号。 
				}
			}
			cout<<s[k-1]<<endl; 
		} 
	}
	
	return 0;
 } 

D. Mark and Lightbulbs

https://codeforces.com/contest/1705/problem/D

#include<stdio.h>
#include<iostream>
#include<algorithm>
#define ll long long
#include<vector>
using namespace std;


int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		string a,b;
		cin>>a>>b;
		vector<ll> aa,bb;//存下a,b序列中的连续的块 
		if(a[0]==b[0] && a[n-1]==b[n-1])
		{
			for(int i=0;i<n-1;i++)
			{
				if(a[i]!=a[i+1])//计算连续的块 
					aa.push_back(i);
				if(b[i]!=b[i+1])
					bb.push_back(i);
			}
			if(aa.size()==bb.size())//看连续的块相同否 
			{
				int num=aa.size();
				ll cnt=0;
				for(int i=0;i<num;i++)
				{
					cnt+=abs(aa[i]-bb[i]);//a中1移动到b相应位置的距离 
				}
				cout<<cnt<<endl;
			}
			else//不相同则永远没有办法变成一样 
				cout<<"-1"<<endl;
		}
		else
		{
			cout<<"-1"<<endl;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值