码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #704 (Div. 2)

时间:2021-02-24 13:20:53      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:min   mes   c++   ret   bit   a*   main   n+1   math   

Codeforces 难得有一次不熬夜的比赛。

A

送分题,记得开 long long。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long
signed main()
{
	int T;
	scanf("%lld",&T);
	while(T--)
	{
		int p,a,b,c;
		scanf("%lld %lld %lld %lld",&p,&a,&b,&c);
		int ta=(p+a-1)/a*a,tb=(p+b-1)/b*b,tc=(p+c-1)/c*c;
		printf("%lld\n",min(min(ta-p,tb-p),tc-p));
	}
	return 0;
}

B

\(\sum\limits_{i = 1}^{n}{n^{n - i} \cdot p_i}\) 可以看作是一个 \(n\) 进制数,所以 \(p_1\) 越大越好,其次是 \(p_2\),以此类推。从 \(n\)\(1\) 枚举,如果当前的数能够安排到前面就安排到前面,按照题意模拟即可。时间复杂度 \(\mathcal O(n)\)(如果实现的好)。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=1e5;
int a[N+10],p[N+10]; 
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) 
		{
			scanf("%d",&a[i]);
			p[a[i]]=i;
		}
		int pos=n+1;
		vector<int> ans;
		for(int i=n;i;i--)
		{
			for(int j=p[i];j<pos;j++) 
				ans.push_back(a[j]);
			if(p[i]<pos) pos=p[i];
		}
		for(int i=0;(unsigned)i<ans.size();i++) printf("%d ",ans[i]);
		putchar(‘\n‘);
	}
	return 0;
}

C

分别对 \(s\) 从前往后和从后往前扫一遍求出 \(pre_i\)\(suf_i\)\(pre_i\) 表示在 \(s\) 中能够满足 \(\forall k\in[1,i],s_{j_k}=t_k\) 的子序列 \(s_{j_1}s_{j_2}\cdots s_{j_i}\)\(1\le j_1<j_2<\cdots< j_i\le n\)) 中最小的 \(j_i\)\(suf_i\) 表示最大的 \(j_i\),答案就是 \(\max\limits_{i=1}^{m-1} \{suf_{i+1}-pre_i\}\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=2e5;
char s[N+10],t[N+10];
int pre[N+10],suf[N+10]; 
int main()
{
	int n,m;
	scanf("%d%d%s%s",&n,&m,s+1,t+1);
	for(int i=1,j=1;i<=n&&j<=m;i++)
	{
		if(s[i]==t[j])
		{
			pre[j]=i;
			j++;
		}
	}
//	for(int i=1;i<=m;i++) printf("%d ",pre[i]);/
	for(int i=n,j=m;i&&j;i--)
	{
		if(s[i]==t[j])
		{
			suf[j]=i;
			j--;
		}
	}
	int ans=0;
	for(int i=1;i<n;i++)
		ans=max(ans,suf[i+1]-pre[i]);
	printf("%d",ans);
	return 0;	
}

D

希望出题人没事。

\(x\) 的二进制表示成 \(x_1x_2\cdots x_{a+b}\)\(y\) 表示成 \(y_1y_2\cdots y_{a+b}\)。令 \(x_1=y_1=1\)\(x_{a+b-k}=y_{a+b}=1\),然后把所有剩余的 \(1\) 安排在满足 \(a_i=b_i=0\) 的位置上即可。如果有任意一个步骤无法满足,则输出 Noreturn 0

要特判 \(\bold{k=0}\)\(\bold{a=0}\) 的情况。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5;
int x[N+10],y[N+10];
int main()
{
	int a,b,k;
	scanf("%d %d %d",&a,&b,&k);
	swap(a,b);
	int n=a+b;
	int ta=a,tb=b;
	if(k==0)
	{
		puts("Yes");
//		ta--;
		for(int i=1;i<=ta;i++) putchar(‘1‘);
		for(int i=1;i<=tb;i++) putchar(‘0‘);
		putchar(‘\n‘); 
		for(int i=1;i<=ta;i++) putchar(‘1‘);
		for(int i=1;i<=tb;i++) putchar(‘0‘);
		return 0;
	}
	if(b==0)
	{
		if(k!=0)
		{
			puts("No");
			return 0;
		}
		else
		{
			puts("Yes");
			for(int i=1;i<=a;i++) putchar(‘1‘);
			putchar(‘\n‘);
			for(int i=1;i<=a;i++) putchar(‘1‘);
			putchar(‘\n‘);
		}
	}
	x[1]=y[1]=1;
	ta--;
	if(ta<0)
	{
		puts("No");
		return 0;
	}
	if(n-k<=1) 
	{
		puts("No");
		return 0;
	}
	x[n-k]=y[n]=1;
	ta--;
	if(ta<0)
	{
		puts("No");
		return 0;
	}
	for(int i=1;i<=n&&ta;i++)
	{
		if(!x[i]&&!y[i])
		{
			x[i]=y[i]=1;
			ta--;
		}
	}
//	if(ta>0)
//	{
//		puts("No");
//		return 0;
//	}
	printf("Yes\n");
	for(int i=1;i<=n;i++) printf("%d",x[i]);
	putchar(‘\n‘);
	for(int i=1;i<=n;i++) printf("%d",y[i]);
}

E

没做出来,先咕着。

Codeforces Round #704 (Div. 2)

标签:min   mes   c++   ret   bit   a*   main   n+1   math   

原文地址:https://www.cnblogs.com/juruo-zzt/p/14438976.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!