Codeforces Round #704 (Div. 2) 题解(待更)

(FST警告)
传送门:https://codeforces.com/contest/1492

A

模拟,分别求出三人到的时间取 \(min\) 即可。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;

ll min_(ll a,ll b){
	if(a>b) return b;
	else return a;
}
int main(){
	int T; cin>>T;
	while(T--){
		ll p,a,b,c; cin>>p>>a>>b>>c;
		ll u,v,w;
		u=a-(p%a==0?a:p%a);
		v=b-(p%b==0?b:p%b);
		w=c-(p%c==0?c:p%c);
		cout<<min_(u,min_(v,w))<<endl;
	}
    return 0;
}

B

化简一下式子,发现就是要求字典序最大的序列,按照操作规则,对于整堆牌,应该将最大的(以及它下面的牌)留在底部最后再放到另一堆,类似的,对于最大的牌上面的牌,也是将最大的(以及它下面的牌)留在底部最后再放到另一堆,如此下去即可。

注意到操作过程需要维护区间最大值,可以打个ST表

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;

const int N=1e5+5,M=20;

int n;
int a[N];

//st
int st[N][M];
int Log[N];
void pre(){
    Log[1]=0;
    FOR(i,2,N-1) Log[i]=Log[i/2]+1;
}

void init(){
    FOR(j,0,M-1)
        for(int i=1;i+(1<<j)-1<=n;i++)
            if(!j) st[i][j]=a[i];
            else st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
}

int query(int l,int r){
    int s=Log[r-l+1];
    return max(st[l][s],st[r-(1<<s)+1][s]);
}

int main(){
	int T; cin>>T;
	pre();
	while(T--){
		cin>>n;
		FOR(i,1,n) cin>>a[i];
		init();

		int pt=n;
		DWN(i,n,1){
			int num=query(1,pt);
			//cerr<<num<<endl;
			if(a[i]==num){
				FOR(j,i,pt) cout<<a[j]<<' ';
				if(i-1) pt=i-1;
			}
		}
		cout<<endl;
	}
    return 0;
}

C

记录一下从左开始b串匹配a串的位置,类似的,记录从右开始b串匹配a串的位置。

然后枚举一下断点就可以了。

比如:

accbcaaabac
abc

从左开始匹配的位置为:
i  ii
accbcaaabac

从右开始匹配的位置为:
       ii i
accbcaaabac

断点可以是:

i
abc

 i
abc

  i
abc

对于第一个断点,对应的序列匹配情况是:

i       i i
accbcaaabac

枚举断点统计一下就好了。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;

const int N=2e5+5;
int f[N],g[N];

int main(){
	int lena,lenb;
	string a,b;
	cin>>lena>>lenb>>a>>b;

	int pt=0;
	char tmp=b[pt];
	//cerr<<tmp;
	for(int i=0;i<lena;i++){
		if(a[i]==tmp && pt<lenb){
			f[pt]=i;
			pt++;
			if(pt<lenb) tmp=b[pt];
		}
	}
	
	pt=lenb-1;
	tmp=b[pt];
	DWN(i,lena-1,0){
		if(a[i]==tmp && pt>=0){
			g[pt]=i;
			pt--;
			tmp=b[pt];
		}
	}
	
	int ans=-1;
	FOR(i,0,lenb-1){
		ans=max(ans,g[i+1]-f[i]);
	}
	
	cout<<ans<<endl;
	
    return 0;
}
posted @ 2021-02-23 19:17  HinanawiTenshi  阅读(159)  评论(0编辑  收藏  举报