Codeforces Round #849 (Div. 4)题解A~G2

Codeforces Round #849 (Div. 4)

A. Codeforces Checking
在这里插入图片描述
大水题,只需要在规定字符串中查找即可

#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
 ll x[maxn];
ll n,d,t;
void solve()
{
	char c;
	cin>>c;
	string s="codeforces";
	if(s.find(c)!=string::npos)
	{
		cout<<"YES"<<endl;
	}
	else
	{
		cout<<"NO"<<endl;
	}
}
 
int main() 
{
cin>>t;
while(t--)
{
solve();
}
}

B. Following Directions

在这里插入图片描述
在这里插入图片描述
由于需要执行的步骤不长,直接检验每执行一次指令之后所移动到的位置是否是目标点即可。


```cpp
#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t;
void solve()
{
int x=0,y=0;
cin>>n;
string s;
cin>>s;
bool flag=0;
for(int i=0;i<s.length();i++)
{
if(s[i]=='R')
{
	x++;
}
else if(s[i]=='L')
{
	x--;
}
else if(s[i]=='U')
{
	y++;
}
else
{
	y--;
	
}
if(x==1&&y==1)
{
		flag=1;
		break;
}
}
if(flag)
{
	cout<<"YES"<<endl;
}
else
{
	cout<<"NO"<<endl;
}
}
 
int main() 
{
cin>>t;
while(t--)
{
solve();
}
}

C. Prepend and Append
在这里插入图片描述
由于每次操作都是在顶端与末端插入1或0,那么我们用两个指针分别从首部以及末尾同时进行查找,直到剩余长度为1或者两个指针的指向相同止

#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t;
void solve()
{
cin>>n;
string s;
cin>>s;
int l=0,r=n-1;
ll ans=0;
while(l<r)
{
 
	int x=s[l]-'0';int y=s[r]-'0';
	if(x^y)
	{
		ans+=2;
		l++;
		r--;
	}
	else
	{
		break;
	}
}
cout<<n-ans<<endl;
}
 
 
int main() 
{
cin>>t;
while(t--)
{
solve();
}
}

D. Distinct Split
在这里插入图片描述

该题要求我们将一个字符串分成两个部分,然后求出每个子串中去重之后还剩余的长度,相加得最大值。只需用两个set容器来进行记录,一个从开头到末尾,一个反之,枚举求最大值即可。

#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t,c;
ll a[maxn];
ll b[maxn];
void solve()
{
cin>>n;
string s,tmp;
cin>>s;
set<char>num1;
set<char>num2;
ll ans=0;
for(int i=0;i<n;i++)
{
num1.insert(s[i]);
a[i]=num1.size();
}
for(int i=n-1;i>=0;i--)
{
	num2.insert(s[i]);
	b[i]=num2.size();
}
for(int i=0;i<n-1;i++)
{
ans=max(ans,a[i]+b[i+1]);
}
cout<<ans<<endl;
}
 
int main() 
{
cin>>t;
while(t--)
{
solve();
}
}

E. Negatives and Positives

在这里插入图片描述
每次我们可以选择两个相邻的数并对他们进行取反,然后求数组和的最大值。实际上,我们只需统计负数的个数即可,如果负数的个数是偶数,那么我们可以将负数全部翻转成正数,此时值最大;如果负数的个数是奇数,无论我们怎么翻转,都会有一个负数存在,不妨将绝对值最小的数变成负数,此时得最大值。

#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t,c;
void solve()
{
cin>>n;
ll ans=0;
ll cnt=0;
vector<int>x;
for(int i=0;i<n;i++)
{
	int tmp;
	cin>>tmp;
	if(tmp<0) cnt++;
	ans+=abs(tmp);
	x.emplace_back(abs(tmp));
}
sort(x.begin(),x.end());
if(cnt%2)
{
ans-=2*x[0];
}
cout<<ans<<endl;
}
 
int main() 
{
cin>>t;
while(t--)
{
solve();
}
}

F. Range Update Point Query
在这里插入图片描述
在这里插入图片描述
当输入1的时候,我们需要对l~r区间的数进行修改,将他们修改成为自身各位数字之和,然而当数小于10的时候,无论怎么修改他都是自己本身,所以,我们只需要记录大于10的数字所在的位置即可,然后再对指定的区间位置进行修改,如果该数修改后小于10,那么便将他的位置记录从记录数组中删去,以减少运算次数。这里我们记录数组用容器set,因为vecor的删除时间复杂度是O(N),会TLE。

#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t,q;
ll a[maxn];
int x[maxn];
int getsum(int tmp)
{
	int sum=0;
	while(tmp)
	{
		sum+=(tmp%10);
		tmp/=10;
	}
	return sum;
}
void solve()
{
cin>>n>>q;
set<int>lo;
for(int i=1;i<=n;i++)
{
	cin>>x[i];
	if(x[i]>=10)
	{
		lo.insert(i);
	}
}
for(int i=1;i<=q;i++)
{
	int type;
	cin>>type;
	if(type==2)
	{
		int l;
		cin>>l;
		cout<<x[l]<<endl;
	}
	else
	{
		int tmp1,tmp2;
		cin>>tmp1>>tmp2;
		vector<int>l;
		for(set<int>::iterator it=lo.lower_bound(tmp1);it!=lo.end()&&(*it)<=tmp2;it++)
		{
			l.emplace_back(*it);
		}
		for(int j=0;j<l.size();j++)
		{
			x[l[j]]=getsum(x[l[j]]);
			if(x[l[j]]<10)
			{
				lo.erase(l[j]);
			}
		}
	}
}
}
 
int main() 
{
cin>>t;
while(t--)
{
solve();
}
}

G1. Teleporters (Easy Version)
在这里插入图片描述
在这里插入图片描述
该题要我们求出,如何用限定的钱去使用最大数量的传送器,左右移动一格会消耗我们1块钱,使用某个点的传送器时会消耗a[i]块钱,由于使用过后我们就会被传送会0点,故只需要将到达每个位置所花的钱与使用该点传送器的钱相加进行排序,遍历即可。

#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define P pair<int,int>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,d,t,c;
ll x[maxn];
void solve()
{
cin>>n>>c;
for(int i=1;i<=n;i++)
{
	cin>>x[i];
	x[i]+=i;
}
sort(x+1,x+1+n);
ll ans=0;
for(int i=1;i<=n;i++)
{
	if(c>=x[i])
	{
		ans++;
		c-=x[i];
	}
	else
	{
		break;
	}
}
cout<<ans<<endl;
}
 
 
int main() 
{
cin>>t;
while(t--)
{
solve();
}

G2. Teleporters (Hard Version)
在这里插入图片描述
在这里插入图片描述
该题与上一题不同的是,每次使用之后我们可以自主选择自己的降落位置到0或者n+1,这样的话,我们用一个对组来记录每个点的最小花费以及从0出发并且使用的花费,之后我们进行枚举,从各个点开始出发,来找出所能使用的最大值。

#include<iostream>
#include<vector>
#include<math.h>
#include<string>
#include<cstring>
#include<map>
#include<bitset>
#include<set>
#include<algorithm>
#include<queue>
#include<bitset>
using namespace std;
#define ll long long
#define P pair<ll,ll>
#define mem(a,b) memset(a,b,sizeof(a));
const int maxn=2e5+10;
ll mod=1e9+1;
ll n,t,c;
P x[maxn];
ll sum[maxn];
void solve()
{
cin>>n>>c;
for(int i=1;i<=n;i++)
{
	cin>>x[i].second;
	x[i].first=min(x[i].second+i,x[i].second+n+1-i);
	x[i].second+=i;
}
sort(x+1,x+n+1);
for(int i=1;i<=n;i++)
{
	sum[i]=sum[i-1]+x[i].first;
}
ll ans=0;
for(int i=1;i<=n;i++)
{
	if(x[i].second<=c)
	{
		ll l=0,r=n,mid;
		while(l<r)
		{
			mid=(l+1+r)/2;
			ll val=sum[mid];
			if(mid>=i)
			{
				val-=x[i].first;
			}
			if(val+x[i].second<=c)
			{
				l=mid;
			}
			else
			{
				r=mid-1;
			}
		}
		ans=max(ans,l+(l<i));
	}
}
cout<<ans<<endl;
}
 
int main() 
{
cin>>t;
while(t--)
{
solve();
}
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值