zoukankan      html  css  js  c++  java
  • 某模拟赛

    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

  • 相关阅读:
    子元素过滤器nth-child解释
    jquery属性选择器中|value和^value的区别
    [转]float,double和decimal类型
    postsharp初体验
    [札记]IL经典指令解析之方法调度
    Oracle问题诊断过程常用SQL
    在chrome浏览器中 页面生成二维码
    音视频实例
    html5 新增input类型与属性
    html5 form-Validity验证函数
  • 原文地址:https://www.cnblogs.com/int-2147483648/p/15056754.html
Copyright © 2011-2022 走看看