Codeforces Round 932 (Div. 2)题解(A-C)

A. Entertainment in MAC

比较原始字符串的首字母和尾字母,另更小的位于最终答案的开头。对结果进行分类讨论,由于进行两次操作1可以将字符串还原,所以只需讨论操作数的奇偶性。

  1. 首字母>尾字母&&操作数为奇:
    倒转字符
  2. 首字母>尾字母&&操作数为偶:
    倒转字符后执行操作2
  3. 首字母<尾字母&&操作数为奇:
    执行操作2
  4. 首字母<尾字母&&操作数为偶:
    不做操作
#include <bits/stdc++.h>
using namespace std;
string s;
int x,n;
void solve()
{
   cin>>x>>s;
   n=s.length();
   int l=0,r=n-1;
   while(s[l]==s[r]&&l<r)
   {
   	l++;
   	r--;
   }
   int flag;
   if(l>=r) cout<<s;
   else if(s[l]<s[r])
   {
   	if(x%2)
   	{
   		cout<<s;
   		for(int i=n-1;i>=0;i--)
   		cout<<s[i];
   	}
   	else
   	{
   		cout<<s;
   	}
   }
   else
   {
   	if(x%2)
   	{
   		for(int i=n-1;i>=0;i--)
   		cout<<s[i];
   	}
   	else
   	{
   		for(int i=n-1;i>=0;i--)
   		cout<<s[i];
   		cout<<s;
   	}
   }
   cout<<"\n";
}
signed main()
{
   int t;
   cin>>t;
   while(t--)
   solve();
}

B. Informatics in MAC

每个子段的MEX一定与整个数组的MEX相同。先找到整个数组的MEX,由于大于MEX的值不会对结果造成影响,故只需保证每个子段都含0~MEX-1。利用set进行计数。

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,r[N];
struct node
{
	int num,ip;
}a[N];
bool cmp1(node x,node y)
{
	if(x.num==y.num) return x.ip<y.ip;
	return x.num<y.num;
}
bool cmp2(node x,node y)
{
	return x.ip<y.ip;
}
void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].num;
		a[i].ip=i;
	}
	sort(a+1,a+1+n,cmp1);
	int flag=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i].num>flag) break;
		if(a[i].num==flag) flag++;
	}
//	printf("flag=%d\n",flag);
	set<int> st;
	int cnt=0;
	int len=0;
	sort(a+1,a+1+n,cmp2);
	for(int i=1;i<=n;i++)
	{
		if(a[i].num<flag&&st.count(a[i].num)==0)
		{
			st.insert(a[i].num);
			cnt++;
		}
//		printf("i=%d cnt=%d\n",i,cnt);
		if(cnt==flag)
		{
			st.clear();
			r[++len]=i;
			cnt=0;
		}
	}
	if(len==1)
	{
		cout<<"-1\n";
		return;
	}
	cout<<len<<"\n";
	for(int i=1;i<len;i++)
	cout<<r[i-1]+1<<" "<<r[i]<<"\n";
	cout<<r[len-1]+1<<" "<<n<<"\n";
}
signed main()
{
	int t;
	cin>>t;
	while(t--)
	solve();
}

C. Messenger in MAC

对于k个message,最小time一定是当b呈升序时。将数组重新按b升序排序,枚举左右端点,此时b的贡献是固定的,将a存入大根堆,计算最多有多少个a。不同情况取最大值

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e3+10;
int n,k;
struct node
{
	int x,y;
}a[N];
bool cmp(node x,node y)
{
	return x.y<y.y;
}
void solve()
{
	int ans=0;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	cin>>a[i].x>>a[i].y;
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++)
	{
		priority_queue<int> p;
		int temp=0;
		for(int j=i;j<=n;j++)
		{
			p.push(a[j].x);
			temp+=a[j].x;
			while(!p.empty()&&a[j].y-a[i].y+temp>k)
			{
				temp-=p.top();
				p.pop();
			}
			ans=max(ans,(int)p.size());
		}
	}
	cout<<ans<<"\n";
}
signed main()
{
	int t;
	cin>>t;
	while(t--)
	solve();
}

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值