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

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

时间:2020-07-03 23:08:21      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:std   i++   映射   排列   关系   flag   哪些   rap   str   

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\n",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\n",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\n");
	else{
		printf("YES\n");
		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? ‘\n‘:‘ ‘);
		for(int i=1;i<=n;i++) printf("%d%c",b[i],i==n? ‘\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\n"),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\n",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\n");
	else{
		printf("Incorrect\n");
		sort(bib.begin(),bib.end());
		printf("\\begin{thebibliography}{99}\n");
		for(auto v:bib){
			cout<<v.sc<<endl;
		}
		printf("\\end{thebibliography}\n");
	}
}

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\n");
        else printf("%lld\n",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\n",sp.size());
	for(auto v:sp){
		printf("%d ",v.sc.size());
		for(auto t:v.sc)
			printf("%d ",t);
		printf("\n");
	}
}

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

标签:std   i++   映射   排列   关系   flag   哪些   rap   str   

原文地址:https://www.cnblogs.com/-aether/p/13233089.html

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