zoukankan      html  css  js  c++  java
  • 【codeforces】【比赛题解】#948 CF Round #470 (Div.2)

    【A】Protect Sheep

    题意:

    一个(R*C)的牧场中有一些羊和一些狼,如果狼在羊旁边就会把羊吃掉。

    可以在空地上放狗,狼不能通过有狗的地方,狼的行走是四联通的。

    问是否能够保护所有的羊不被狼吃掉,如果能输出方案。

    题解:

    判断是否有羊的旁边有狼,有的话就-1。没有的话把所有空地换成狗就好。

    #include<bits/stdc++.h>
    #define F(i,a,b) for(int i=a;i<=(b);++i)
    #define F2(i,a,b) for(int i=a;i<(b);++i)
    using namespace std;
    int n,m,ok=1;
    char str[501][505];
    int main(){
    	scanf("%d%d",&n,&m);
    	F(i,1,n){
    		scanf("%s",str[i]);
    	}
    	F(i,1,n){
    		F2(j,0,m){
    			if(str[i][j]=='S'&&(str[i-1][j]=='W'||str[i][j-1]=='W'||str[i+1][j]=='W'||str[i][j+1]=='W')) ok=0;
    		}
    	}
    	if(ok){
    		puts("Yes");
    		F(i,1,n){
    			F2(j,0,m){
    				printf("%c",str[i][j]=='.'?'D':str[i][j]);
    			}
    			puts("");
    		}
    	}
    	else puts("No");
    	return 0;
    }
    

    【B】Primal Sport

    题意:

    初始有一个数(X_0),每一次可以对(X_i)这个数进行一个操作变成(X_{i+1}):

    选择一个小于(X_i)的质数(p),则(X_{i+1})等于(leftlceilfrac{X_i}{p} ight ceilcdot p)。

    给定了(X_2),问最小的可能(X_0)。

    题解:

    令(p_1)等于(X_2)的最大质因数,那么显然(X_1)可能为([X_2-p_1+1,X_2])中的合数。

    再对这个范围内的(X_1)执行相同的过程即可。

    #include<bits/stdc++.h>
    #define F(i,a,b) for(int i=a;i<=(b);++i)
    using namespace std;
    const int INF=0x3f3f3f3f;
    
    int n,ans=INF;
    
    int np[1000001]={1,1},pr[1000001],cnt;
    int maxp[1000001];
    
    void init(int num){
    	F(i,2,num){
    		if(!np[i]) pr[++cnt]=i, maxp[i]=i;
    		F(j,1,cnt){
    			if(i*pr[j]>num) break;
    			np[i*pr[j]]=1;
    			maxp[i*pr[j]]=maxp[i];
    			if(i%pr[j]==0) break;
    		}
    	}
    }
    
    int main(){
    	init(1000000);
    	scanf("%d",&n);
    	F(i,n-maxp[n]+1,n)
    		if(maxp[i]!=i) ans=min(ans,i-maxp[i]+1);
    		else ans=min(ans,i);
    	printf("%d",ans);
    	return 0;
    }
    

    【C】Producing Snow

    题意:

    每天Bob都能用造雪机造出体积(V_i)的一堆雪,但是现在是夏天,每天每堆雪都会融化(T_i)体积(如果不足(T_i)则全部融化掉)。

    问每天会融化多少体积的雪?

    题解:

    简单set+lower_bound,就很显然。注意点:multiset。

    #include<bits/stdc++.h>
    #define F(i,a,b) for(int i=a;i<=(b);++i)
    #define F2(i,a,b) for(int i=a;i<(b);++i)
    #define dF(i,a,b) for(int i=a;i>=(b);--i)
    #define dF2(i,a,b) for(int i=a;i>(b);--i)
    #define eF(i,u) for(int i=h[u];i;i=nxt[i])
    #define ll long long
    #define ld double
    using namespace std;
    
    int n;
    ll v[100001],t[100001];
    ll ans,sum;
    multiset<ll> st;
    
    int main(){
    	scanf("%d",&n);
    	F(i,1,n) scanf("%lld",v+i);
    	F(i,1,n) scanf("%lld",t+i);
    	F(i,1,n){
    		st.insert(v[i]+sum);
    		multiset<ll>::iterator it,it2,it3;
    		sum+=t[i];
    		ans=t[i]*st.size();
    		it=st.lower_bound(sum+1);
    		for(it2=st.begin();it2!=st.end()&&it2!=it;){
    			ans+=*it2-sum;
    			it3=it2; ++it2;
    			st.erase(it3);
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    【D】Perfect Security

    题意:

    有一个长度为(n)的数组(A),和一个等长的数组(B),要求你重排数组(B),使得序列(A_1oplus B_1,A_2oplus B_2,cdots,A_noplus B_n)在字典序上最小。

    题解:

    从1到n遍历每一个(A_i),选出当前(B)中的让(A_ioplus B_i)最小的(B_i)即可,重复(n)遍。

    那么每次必须要在较快时间内完成,考虑set内按二进制位二分。每次可以(log^2n)完成。

    #include<bits/stdc++.h>
    #define F(i,a,b) for(int i=a;i<=(b);++i)
    #define dF(i,a,b) for(int i=a;i>=(b);--i)
    using namespace std;
    
    int n,a[300001];
    multiset<int> b;
    
    int main(){
    	int x;
    	scanf("%d",&n);
    	F(i,1,n) scanf("%d",a+i);
    	F(i,1,n) scanf("%d",&x), b.insert(x);
    	F(i,1,n){
    		int now=0;
    		dF(j,29,0){
    			if((a[i]>>j)&1){
    				now+=1<<j;
    				multiset<int>::iterator it1=b.lower_bound(now), it2=b.lower_bound(now+(1<<j));
    				if(it1==it2)
    					now-=1<<j;
    			}
    			else{
    				multiset<int>::iterator it1=b.lower_bound(now), it2=b.lower_bound(now+(1<<j));
    				if(it1==it2)
    					now+=1<<j;
    			}
    		}
    		b.erase(b.lower_bound(now));
    		printf("%d ",a[i]^now);
    	}
    	return 0;
    }
    

    【E】Picking Strings

    题意:

    对于一个只含有( extbf{A,B,C})的字符串,可以做以下变化:

    ( extbf{A}Rightarrow extbf{BC})

    ( extbf{B}Rightarrow extbf{AC})

    ( extbf{C}Rightarrow extbf{AB})

    ( extbf{AAA}Rightarrow varnothing)

    给定两个字符串(S)和(T),有(Q)个询问:

    每个询问为问(S[a...b])能否通过以上变换变成(T[c...d])。

    题解:

    考虑( extbf{B}Rightarrow A extbf{C}Rightarrow AA extbf{B}Rightarrow extbf{AAA}CRightarrow C)和( extbf{C}Rightarrow A extbf{B}Rightarrow AA extbf{C}Rightarrow extbf{AAA}BRightarrow B)。

    这表示了( extbf{B}; extbf{C})之间可以互相转化。

    考虑( extbf{B}Rightarrow A extbf{C}Rightarrow AA extbf{B}Rightarrow AAA extbf{C}Rightarrow A extbf{AAA}BRightarrow AB)和(A extbf{B}Rightarrow AA extbf{C}Rightarrow extbf{AAA}BRightarrow B)。

    这表示了一个( extbf{B})之前的( extbf{A})的个数可以任意地增加或减少,同理( extbf{C})也一样。

    那么又因为( extbf{A})可以变成( extbf{BC}),也就是说原字符串只要有至少一个( extbf{B})或者( extbf{C}),就可以把( extbf{B})或者( extbf{C})的个数任意地加二。

    所以原字符串和目标字符串中的( extbf{B})或者( extbf{C})的个数必须奇偶性相同,并且目标字符串的( extbf{B})或者( extbf{C})的个数必须大于等于原字符串的个数。

    最后考虑字符串末尾的( extbf{A}),它们之后没有任何一个( extbf{B})或者( extbf{C})。

    那么可以实现个数减三或者把其中一个( extbf{A})变成( extbf{BC}),这两种操作都无法增加字符串末尾的( extbf{A})的个数。

    那么只要原字符串中末尾( extbf{A})的个数小于目标字符串中的个数,就无法实现。

    如果原字符串中( extbf{B})或者( extbf{C})的个数等于目标字符串中的个数,就不能进行第二个操作,只能进行第一个操作。

    那么分类讨论就到此结束。

    综上所述,我们要知道原字符串和目标字符串的( extbf{B})或者( extbf{C})的个数和末尾的( extbf{A})的个数。

    可以用简单的前缀和实现。

    代码奉上:

    #include<bits/stdc++.h>
    #define F(i,a,b) for(int i=a;i<=(b);++i)
    using namespace std;
    
    char str1[100005],str2[100005];
    int len1,len2;
    int sbc1[100005],sbc2[100005];
    int sua1[100005],sua2[100005];
    int Q;
    
    int main(){
    	scanf("%s%s",str1+1,str2+1);
    	len1=strlen(str1+1), len2=strlen(str2+1);
    	F(i,1,len1) sbc1[i]=sbc1[i-1]+(str1[i]=='B'||str1[i]=='C');
    	F(i,1,len2) sbc2[i]=sbc2[i-1]+(str2[i]=='B'||str2[i]=='C');
    	F(i,1,len1) sua1[i]=str1[i]=='A'?sua1[i-1]+1:0;
    	F(i,1,len2) sua2[i]=str2[i]=='A'?sua2[i-1]+1:0;
    	scanf("%d",&Q);
    	while(Q--){
    		int a,b,c,d;
    		scanf("%d%d%d%d",&a,&b,&c,&d);
    		int sumbc1=sbc1[b]-sbc1[a-1], sumbc2=sbc2[d]-sbc2[c-1];
    		int sufa1=min(sua1[b],b-a+1), sufa2=min(sua2[d],d-c+1);
    		if((sumbc1&1)!=(sumbc2&1)||sumbc1>sumbc2||sufa1<sufa2) {putchar('0'); continue;}
    		if(sumbc1==sumbc2)
    			if(sufa1%3==sufa2%3) putchar('1');
    			else putchar('0');
    		else
    			if(sumbc1==0) putchar(sufa1>sufa2?'1':'0');
    			else putchar('1');
    	}
    	return 0;
    }
  • 相关阅读:
    微服务-分布式事务解决方案
    Python cannot import name 'Line' from 'pyecharts'
    powershell 基础
    Linux SSH config
    神奇的Python代码
    GitHub 中 readme 如何添加图片
    Linux 笔记(自用)
    Anaconda 安装 TensorFlow ImportError:DLL加载失败,错误代码为-1073741795
    Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default
    Git入门教程 Git教程入门
  • 原文地址:https://www.cnblogs.com/PinkRabbit/p/8548843.html
Copyright © 2011-2022 走看看