XIX Russia Team Open, High School Programming Contest 解题报告

Posted -aether

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XIX Russia Team Open, High School Programming Contest 解题报告相关的知识,希望对你有一定的参考价值。

A

温暖的签到题。

#include <bits/stdc++.h>

using namespace std;

#define ll long long
ll input(){
	ll x=0,f=0;char ch=getchar();
	while(ch<‘0‘||ch>‘9‘) f|=ch==‘-‘,ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
	return f? -x:x;
}

const int N=2e5+7;
ll a[N],mx[N],m[N];

int main(){
	int n=input();
	ll mxx=0;
	for(int i=1;i<=n;i++){
		m[i]=input();
		for(int j=1;j<=m[i];j++){
			ll x=input();
			mx[i]=max(mx[i],x);
		}
		mxx=max(mx[i],mxx);
	}

	ll Ans=0;
	for(int i=1;i<=n;i++){
		Ans+=(mxx-mx[i])*m[i];
	}
	printf("%lld
",Ans);
}

M

尺取法,温暖的签到题。

#include <bits/stdc++.h>
 
using namespace std;
 
#define ll long long
ll input(){
	ll x=0,f=0;char ch=getchar();
	while(ch<‘0‘||ch>‘9‘) f|=ch==‘-‘,ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
	return f? -x:x;
}
 
const int N=1e5+7;
 
int a[N];
 
int main(){
	int n=input(),k=input();
 
	for(int i=1;i<=n;i++){
		a[i]=input();
	}
 
	int Ans=1;
 
	for(int r=1,l=1;r<=n;r++){
		if(r-l+1>1){
			if(a[r]!=a[r-1]) Ans=max(r-l+1,Ans);
			else l=r;
		}
	}
	printf("%d
",Ans);
}

D

构造,易知如果题目给了(frac{n(n-1)}{2})个以上的大小关系,那么a数组与b数组已经被确定,又因为a数组是一个排列,所以b数组必定无法满足条件。我们可以找到一个所给大小关系不包括的两个位置,强行让这两个位置满足条件,其它位置让a,b的对应值相等,即可满足题设条件。

#include <bits/stdc++.h>

using namespace std;

#define ll long long
ll input(){
	ll x=0,f=0;char ch=getchar();
	while(ch<‘0‘||ch>‘9‘) f|=ch==‘-‘,ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
	return f? -x:x;
}

const int N=1e5+7;

int n,m;
map <int,int> mp[N];
int a[N],b[N];

int main(){
	n=input(),m=input();

	for(int i=1;i<=m;i++){
		int l=input(),r=input();
		if(l>r) swap(l,r);
		mp[l][r]=1;
	}

	int flag=1,posi,posj;
	for(int i=1;i<=n&&flag;i++){
		for(int j=i+1;j<=n&&flag;j++){
			if(!mp[i][j]){
				posi=i,posj=j;
				flag=0;
			}
		}
	}

	if(flag) printf("NO
");
	else{
		printf("YES
");
		b[posi]=1,b[posj]=1;
		a[posi]=1,a[posj]=2;
		int cnt=2;
		for(int i=1;i<=n;i++){
			if(i==posi||i==posj) continue;
			a[i]=b[i]=++cnt;
		}
		for(int i=1;i<=n;i++) printf("%d%c",a[i],i==n? ‘
‘:‘ ‘);
		for(int i=1;i<=n;i++) printf("%d%c",b[i],i==n? ‘
‘:‘ ‘);
	}
}

L

考虑单周,双周,所有时间对答案的影响,不妨设单周为(odd),双周为(even),所有时间能承载的人数为(frac{odd*a+even*b}{k}),单周承载人数为(frac{odd*a}{k-even}),双周承载人数为(frac{even*b}{k-odd}),故答案最小值为这三个数中最小值。不过考虑答案的可行性,要保证分母为正整数,不满足条件的情况不需要考虑。

#include <bits/stdc++.h>

using namespace std;

#define ll long long
ll input(){
	ll x=0,f=0;char ch=getchar();
	while(ch<‘0‘||ch>‘9‘) f|=ch==‘-‘,ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
	return f? -x:x;
}

ll t,n,a,b,k;

int main(){
	t=input(),n=input(),a=input(),b=input(),k=input();
	ll odd,even;
	odd=n/2+n%2;
	even=n/2;

	if(n<k) printf("0
"),exit(0);

	ll Ans=(a*odd+b*even)/k;
	if(k>even) Ans=min((a*odd)/(k-even),Ans);
	if(k>odd) Ans=min((b*even)/(k-odd),Ans);

	printf("%lld
",min(Ans,t));
}

B

模拟题,看见(LaTeX)还感觉挺亲切的(之前帮老师用LaTeX排版论文,熬了通宵)。拿个map存一下顺序,直接在bibliography里匹配就好了。

#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define pb push_back
#define PIS pair <int,string>
#define fr first
#define sc second
#define mp make_pair


string tex;
vector <PIS> bib;
map <string,int> bid;

void input(){
	string s;
	while(getline(cin,s)){
		if(s=="\begin{thebibliography}{99}") break;
		tex+=s;
	}
	bib.clear();
	int cnt=0;
	while(getline(cin,s)){
		if(s=="\end{thebibliography}") break;
		bib.pb(mp(++cnt,s));
	}
}

string getname(int pos){
	string res;
	for(int i=pos;;i++){
		if(tex[i]==‘}‘) break;
		res+=tex[i];
	}
	return res;
}

bool work(){
	int id=0;
	for(int i=0;i<tex.length();i++){
		if(tex[i]==‘\‘&&tex[i+1]==‘c‘&&tex[i+2]==‘i‘&&tex[i+3]==‘t‘&&tex[i+4]==‘e‘&&tex[i+5]==‘{‘){
			bid[getname(i+6)]=++id;
		}
	}
	// for(auto v:bid){
	// 	cout<<v.fr<<" "<<v.sc<<endl;
	// }

	int f=1;

	for(auto &v:bib){
		string s=v.sc,name="";;
		int id=v.fr,now=9;

		while(s[now]!=‘}‘){
			name+=s[now++];
		}
		
		if(bid[name]!=id){
			f=0;
			v.fr=bid[name];
		}
	}
	return f;
}

int main(){
	input();
	int flag=work();
	if(flag) printf("Correct
");
	else{
		printf("Incorrect
");
		sort(bib.begin(),bib.end());
		printf("\begin{thebibliography}{99}
");
		for(auto v:bib){
			cout<<v.sc<<endl;
		}
		printf("\end{thebibliography}
");
	}
}

I

第一次发觉unsigned int的编码的原理会导致unsigned int里存的数是对(2^{32})取模的,这个地方wa了不少。其它没啥好说的,对于每一个数,找一个他前面比他小的数中最小的,找他后面比他大的数中最大的即可。

#include <bits/stdc++.h>

using namespace std;

#define ll long long
ll input(){
	ll x=0,f=0;char ch=getchar();
	while(ch<‘0‘||ch>‘9‘) f|=ch==‘-‘,ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
	return f? -x:x;
}

const int N=2e7+7;

const ll mod=1ll<<32;
const ll inf=9223372036854775806;

ll a[N];
unsigned int b[N],x,y,z;

ll _min(ll a,ll b){
	if(a<b) return a;
	else return b;
}

ll _max(ll a,ll b){
	if(a>b) return a;
	else return b;
}

int main(){
	int T=input();

	while(T--){
		ll n=input(),l=input(),r=input();x=input(),y=input(),z=input();
		for(int i=0;i<=n+7;i++) a[i]=b[i]=0;
		b[1]=input(),b[2]=input();
		for(int i=3;i<=n;i++){
			b[i]=(b[i-2]*x%mod+b[i-1]*y%mod+z)%mod;
		}

		for(int i=1;i<=n;i++){
			a[i]=b[i]%(r-l+1)+l;
		}

		// for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl<<endl;

		ll mi=inf,mx=-inf;

        ll Ans=inf;

        for(int i=1;i<=n;++i){
        	if(mi<a[i])Ans=_min(a[i]*mi,Ans);
        	mi=_min(a[i],mi);
        }

        for(int i=n;i>=1;--i){
        	if(mx>a[i]) Ans=_min(a[i]*mx,Ans);
        	mx=_max(a[i],mx);
        }

        if(Ans==inf) printf("IMPOSSIBLE
");
        else printf("%lld
",Ans);
	}
}

K

对于循环节我们需要知道出现过了哪些字符。对于串首,串首末尾的与循环节成分相同的字符我们可以去掉。要满足题目条件我们需要经过我们处理的串首要相等并且循环节成分相同我们便可以认为这两个串互为子序列。那么我们拿map映射一下就可以解决问题了。

#include <bits/stdc++.h>

using namespace std;

#define ll long long
ll input(){
	ll x=0,f=0;char ch=getchar();
	while(ch<‘0‘||ch>‘9‘) f|=ch==‘-‘,ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
	return f? -x:x;
}

#define PII pair <string,string>
#define fr first
#define sc second
#define mp make_pair
const int N=1e5+7;

map<PII,vector<int>> sp;
PII a[N];

int main(){
	int n=input();
	for(int i=1;i<=n;i++){
		cin>>a[i].fr>>a[i].sc;
		string t1="0";
		string t2="00000000000000000000000000";
		for(int j=0;j<a[i].sc.length();j++){
			t2[a[i].sc[j]-‘a‘]=‘1‘;
		}
		int j;
		for(j=a[i].fr.size()-1;j>=0;j--){
			if(t2[a[i].fr[j]-‘a‘]==‘0‘) break;
		}

		for(int k=0;k<=j;k++){
			t1+=a[i].fr[k];
		}
		// cout<<t1<<" "<<t2<<endl;
		sp[mp(t1,t2)].push_back(i);
	}

	printf("%d
",sp.size());
	for(auto v:sp){
		printf("%d ",v.sc.size());
		for(auto t:v.sc)
			printf("%d ",t);
		printf("
");
	}
}

以上是关于XIX Russia Team Open, High School Programming Contest 解题报告的主要内容,如果未能解决你的问题,请参考以下文章

2020-2021 Russia Team Open, High School Programming Contest G题(带花树)

Gym.102059: 2018-2019 XIX Open Cup, Grand Prix of Korea(寒假gym自训第一场)

2018-2019 XIX Open Cup, Grand Prix of Korea (Division 2) GYM 102058 F SG函数

翻译‘BadRabbit’ Ransomware Burrows Into Russia, Ukraine

2019.1.7 Russia temperature control demo

UITableViewCell 保持突出显示是不是违反 HIG?