某模拟赛

A.病毒传播

1s

Description

培养皿可以看作一个m行n列的网格。
初始时一些格子放有病毒。
有两种病毒,第一种是ALPHA病毒,它的特点是如果一个格子四连通与ALPHA病毒相连,那么这个格子第二天也会感染ALPHA病毒。 第二种是DELTA病毒,它的特点是如果一个格子八连通与DELTA病毒相连,那么这个格子第二天也会感染DELTA病毒。
一个格子如果感染了ALPHA病毒或DELTA病毒,那么这个病毒会永久存在在这个格子当中。两种病毒可以在同一个格子中共存。
现在小Z想问问你,T天过去以后,哪些格子里有病毒。
ps. 四连通指格子的上下左右相邻,八连通为上下左右,左上,右上,左下,右下相邻。

(1leq n,mleq 500,1leq Tleq 10^9)

Solution

模拟即可(全部感染时提前break),复杂度(O(n^3))

Code

#include<bits/stdc++.h>
using namespace std;
int read(){
	int w=0,f=1;char c=getchar();
	while (c<'0'||c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0'&&c<='9'){
		w=w*10+c-'0';
		c=getchar();
	}
	return w*f;
}
const int N=505;
int n,m,T,a[N][N],cnt;
void solve(int x,int y,int k){
	if(k==2){
		if(x-1>0) if(!a[x-1][y]) ++cnt,a[x-1][y]=2;else a[x-1][y]=2;
		if(y-1>0) if(!a[x][y-1]) ++cnt,a[x][y-1]=2;else a[x][y-1]=2;
		if(x+1<=n)if(!a[x+1][y]) ++cnt,a[x+1][y]=2;else a[x+1][y]=2;
		if(y+1<=m)if(!a[x][y+1]) ++cnt,a[x][y+1]=2;else a[x][y+1]=2;
		if(x-1>0&&y-1>0)  if(!a[x-1][y-1]) ++cnt,a[x-1][y-1]=2;else a[x-1][y-1]=2;
		if(y-1>0&&x+1<=n) if(!a[x+1][y-1]) ++cnt,a[x+1][y-1]=2;else a[x+1][y-1]=2;
		if(x+1<=n&&y+1<=m)if(!a[x+1][y+1]) ++cnt,a[x+1][y+1]=2;else a[x+1][y+1]=2;
		if(y+1<=m&&x-1>0) if(!a[x-1][y+1]) ++cnt,a[x-1][y+1]=2;else a[x-1][y+1]=2;
	}
	if(k==1){
		if(x-1>0 &&!a[x-1][y]) ++cnt,a[x-1][y]=1;
		if(y-1>0 &&!a[x][y-1]) ++cnt,a[x][y-1]=1;
		if(x+1<=n&&!a[x+1][y]) ++cnt,a[x+1][y]=1;
		if(y+1<=m&&!a[x][y+1]) ++cnt,a[x][y+1]=1;
	}
}
queue<pair<pair<int,int>,int> > q;
pair<pair<int,int>,int> mtlyk(int qa,int qb,int qc){return make_pair(make_pair(qa,qb),qc);}
void bfs(){
	for(int i=1;i<=n;++i)	
		for(int j=1;j<=m;++j)
			if(a[i][j])
				q.push(mtlyk(i,j,a[i][j]));
	while(!q.empty()){solve(q.front().first.first,q.front().first.second,q.front().second);q.pop();}
}
int main(){
	n=read();m=read();T=read();char c;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			{cin>>c;if(c=='A') a[i][j]=1,++cnt;if(c=='D') a[i][j]=2,++cnt;}
	while(T--){bfs();if(cnt==n*m) break;}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j)
			printf("%d ",(a[i][j]?1:0));
		printf("
");
	}
	return 0;
}

B.双倍逆序

1s

Description

给定一个(n)个数字的序列(a_1, a_2, ldots, a_n) ,问双倍逆序对的数量是多少。
双倍逆序对的定义如下,一组(i,j)满足(i<j,a_i > 2 a_j)为一对双倍逆序对。

(1leq nleq 10^5,1leq a_i leq 10^8)

Solution

归并排序求逆序对,魔改一下就行了,复杂度(O(nlog n))

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
	int w=0,f=1;char c=getchar();
	while (c<'0'||c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0'&&c<='9'){
		w=w*10+c-'0';
		c=getchar();
	}
	return w*f;
}
const int N=100005;
int sortme[N],n,a[N],ans,cnt;
void msor(int l,int r){
	//cout<<l<<r<<' ';
	if(l==r) return;
	int mid=((l+r)>>1);
	msor(l,mid);msor(mid+1,r);
	for(int i=mid+1,j=l;i<=r;++i){
		while(a[j]>(a[i]<<1)&&j<=mid) ++j;
		ans+=j-l;
	}
	int j=l;cnt=0;
	for(int i=mid+1;i<=r;++i){
		while(a[j]>a[i]&&j<=mid) sortme[cnt++]=a[j++];
		sortme[cnt++]=a[i];
	}
	while(j<=mid) sortme[cnt++]=a[j++];
	//for(int i=0;i<cnt;++i) cout<<sortme[i]<<' '; cout<<l<<r<<endl;
	for(int i=0;i<cnt;++i) a[l+i]=sortme[i];
	return;
}
signed main(){
	n=read();
	for(int i=1;i<=n;++i) a[i]=read();
	msor(1,n);
	//for(int i=1;i<=n;++i) printf("%lld ",a[i]);
	printf("%lld",ans);
	return 0;
}

C.MaxGCD

1s

Description

(gcd(S)) 表示集合(S)中所有元素的GCD。给定可重集(A)(Q)次询问,每次给定整数(k),求

[max_{Ssubseteq A,|S|=k} gcd(S) ]

(2leq nleq 5e5,1leq a_ileq 10^6,1leq Qleq n,2leq kleq n)

Solution

(M=max_i a_i)
枚举[1,M]中的整数(记为(i)),枚举(i)的倍数,统计(A)(i)倍数的个数。记tot[i]表示(A)(i)倍数的个数。
ans[i]表示(k)(i)时的答案。有(ans[i]geq j(ileq tot[j]) 倒序枚举)i(,每次将ans[last+1]~ans[tot[i]]赋值为)i(即可。 复杂度)O(nln n)$

Code

#include<bits/stdc++.h>
using namespace std;

int read(){
	int w=0,f=1;char c=getchar();
	while (c<'0'||c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0'&&c<='9'){
		w=w*10+c-'0';
		c=getchar();
	}
	return w*f;
}
int mxtot=1,n,Q,maxx,t[1000006],tot[1000006],ans[500005];
int main(){
	n=read();Q=read();
	for(int i=1,a;i<=n;++i) a=read(),maxx=max(maxx,a),++t[a];
	for(int i=maxx;i>0;--i){
		for(int j=i;j<=maxx;j+=i)
			tot[i]+=t[j];
		for(int j=mxtot+1;j<=tot[i];++j) ans[j]=i;
		mxtot=max(mxtot,tot[i]);
	}
	while(Q--){printf("%d
",ans[read()]);}
	return 0;
}

D.旅游路线

3s

Description

小Z所在的国家有n个城市,这n个城市之间由无向道路相连,并且任意两个不同的城市之间有且仅有一条路径连接。
APP预设了k个旅行路线,每个旅行路线都是一条路径,每条路径p->q由一个起点p和一个终点q定义,代表着旅行路线为通过无向道路不经过重复点从城市p出发前往城市q。 这k条路径分别有互不相同的推荐值w[i]。推荐值越高表示这条路径越被推荐。
由于疫情的原因,一些城市会封城,无法通行。在本题中,同时只会有一个城市爆发疫情。
现在小Z想添加一个功能,当给定封城城市时,在所有可成行的路径中推荐值在[L,R]区间内APP最推荐的路径是哪条。
你需要实现这个功能,并多次回答相互独立的询问(即,每次询问中封城的城市以该次询问为准)。
如果APP有最推荐的路径,请输出最推荐路径的推荐值。如果没有路径可以推荐,请输出-1。

Solution

Code

原文地址:https://www.cnblogs.com/int-2147483648/p/15056754.html