Educational Codeforces Round 130 (Rated for Div. 2)

目录

A. Parkway Walk

题意:

思路:

代码:

B. Promo

题意:

思路:

代码:

C. awoo's Favorite Problem(!)

题意:

思路1:

代码1:

思路2:

代码2:


A. Parkway Walk

(点击可以跳转至题目)

题意:

有一段路,走一步会消耗一个能量(起始能量会给),路中间有座位可以恢复任意能量。求走完路所需要恢复的最小能量值。

思路:

起始能量够走完全程就输出0,不然就直接用距离减去起始能量。

代码:


#include<bits/stdc++.h>
using namespace std;
int main()
{
	long long t,n,m;
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		long long sum=0;
		while(n--)
		{
			long long k;
			cin>>k;
			sum+=k; 
		}
			if(sum<=m)
				cout<<0<<endl;
			else
				cout<<sum-m<<endl;
		
	}
 } 

B. Promo

题意:

一堆商品在做活动,买x件,其中最便宜的y件可以免费,输出不同x、y最多可以免费的金额。

思路:

先从大到小排,答案就是前x件里面倒序y件的价格和。

不过暴力会T(wa一次)。

所以用前缀和,因为太大没有开long long(wa两次)。

然后i、j这样的索引也要开(wa一次)最后斗胆尝试才过了QAQ

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+3;
long long a[maxn];
long long before[maxn];
bool cmp(int x,int y)
{
	return x>y;
}
int main()
{
	long long n,q;
	cin>>n>>q;
	for(long long i=0;i<n;i++)
	{
		cin>>a[i];
	}
	sort(a,a+n,cmp);
	int j=0;
	before[0]=0;
	for(long long i=1;i<=n;i++)
	{
		before[i]=before[i-1]+a[j++];
	}
	for(long long i=0;i<q;i++)
	{
		long long x,y;
		cin>>x>>y;
		cout<<before[x]-before[x-y]<<endl;
	}
 } 

C. awoo's Favorite Problem(!)

题意:

给两个长度为 n 的字符串 s 和 t。两个字符串都是由“a”、“b”或“c”组成。

有两种操作:

1.选择 s 中出现的“ab”并将其替换为“ba”;
2.选择 s 中出现的“bc”并将其替换为“cb”。

不限制操作次数,可以改变字符串 s 使它等于字符串 t 吗

思路1:

我们依次比较,不同就向后寻找需要的字符,只要满足条件没有阻拦因素就交换,否则就是不能通过变换得到两个相同字符串的。

当匹配不成功时:

1.首先 交换串字符 不能为c,因为c无法变成原串想要的a或者b。(cb、ca、cc都是不满足条件的)。

2.如果原串字符是a,(排除1),则交换串字符是b,那没办法了,a只能通过和b交换使自己位置越来越靠后。(ba不能变成ab)-------NO。

3.如果原串字符是b,想得到b的话需要靠a,b可以通过和a交换 使自己向前冲(遇到c阻拦就冲不动啦)。就是aaaaaaab(OK),aaaaacb(NO)。

3.如果原串字符是c,想得到c的话需要靠b,c可以通过和b交换 使自己向前冲(遇到a阻拦就冲不动啦)。就是bbbbbbbc(OK),bbbbbac(NO)。

代码1:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
    	string s, t;
    	cin >> n >> s >> t;//把s变成t 
    	int ib = 0, ia = 0,flag=0;
    	for(int i=0;i<n;i++)
    	{
    		 ia=max(ia,i);//取最大值是因为前面的比较过了,取i也是可以的,反正循环也会走到正确的ia 
    		 ib=max(ib,i);
    		if(s[i]!=t[i])//不能匹配时 
    		{
    			if(s[i]=='c')//c想变成a和b都是不可能的
				{
					flag=1;
					break;
				 } 
				if(t[i]=='a')
				//因为a只能通过交换向后移动,所以之后再怎么变换也不会使当前为a 
				{
					flag=1;
					break;
				 } 	
				 if(t[i]=='b')//b可以通过和很多a交换而向前移动(只要没有c阻挠) 
				{
					while(s[ia]=='a'&&ia<n)
						ia++;
					if(s[ia]=='c'||ia>=n)//遇到了c或者到结尾都只有a一个人 
					{
						flag=1;
						break;
					}
					else
					{
						swap(s[ia],s[i]);
					}
				}
				else if(t[i]=='c')//c可以通过和很多b交换而向前移动(只要没有a阻挠)
				{
					while(s[ib]=='b'&&ib<n)
						ib++;
					if(s[ib]=='a'||ib>=n)//遇到了a或者到结尾都只有b一个人
					{
						flag=1;
						break;
					}
					else
					{
						swap(s[ib],s[i]);
					}
				}
				
			}
		}
		if(flag)
			cout<<"NO"<<endl;
		else
			cout<<"YES"<<endl;
	}
 } 

思路2:

1.首先三个字符的个数要相同,这里用到了count函数计数:

在c++的algorithm中,用于在一对迭代器中寻找指定值val出现的次数。
例: count(s.begin().s.end(),val);

2.ab、bc交换意味着b可以前后移动,所以b的位置不重要。统计两个字符串里a、c分别出现的位置。这里是用vector记录的。

因为c可以通过交换向前移动,所以只要 交换串里c的位置 不小于 原串里c的位置就行(毕竟c向后移动是不太行的)。

同理,因为a可以通过交换向后移动,所以只要 交换串里a的位置 不于大 原串里a的位置就行(毕竟a向前移动是不太行的)。

(我的cf怎么又又又又又进不去了)

代码2:

#include <iostream>
#include<cstring>
#include<vector>
using namespace std;
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
void Solve()
{
	int n;
	cin >> n;
	string s, t;
	cin >> s >> t;
	for (auto ch : { 'a','b','c' })
	{
		if (count(s.begin(), s.end(), ch) != count(t.begin(), t.end(), ch))
		{
			cout << "NO\n";
			return;
		}
	}
	string smalls, smallt;//用于比较ac相对位置 
	vector<int> sa, sc, ta, tc;
	for (int i = 0; i < n; i++)
	{
		if (s[i] == 'a')
		{
			smalls += s[i];	sa.pb(i);
		}
		else if (s[i] == 'c')
		{
			smalls += s[i];	sc.pb(i);
		}
		if (t[i] == 'a')
		{
			smallt += t[i];	ta.pb(i);
		}
		else if (t[i] == 'c')
		{
			smallt += t[i];	tc.pb(i);
		}
	}
	if (smalls != smallt)
	{
		cout << "NO\n";
		return;
	}
	for (int i = 0; i < sa.size(); i++)
	{
		if (sa[i] > ta[i])
		{
			cout << "NO\n";
			return;
		}
	}
	for (int i = 0; i < sc.size(); i++)
	{
		if (sc[i] < tc[i])
		{
			cout << "NO\n";
			return;
		}
	}
	cout << "YES\n";
}
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		Solve();
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序和三三总有一个能跑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值