zoukankan      html  css  js  c++  java
  • 2020 CCPC Wannafly Winter Camp Day6 解题报告

    N


    白给题,⽆论怎么进⾏合并,最后的答案⼀定是 a[1…n] 两两的乘积之和。


    n = int(input())
    a = list(map(int, input().split()))
    ans = 0
    for i in range(0, n):
        for j in range(i+1, n):
            ans += a[i] * a[j]
    print(ans)
    

    K


    白给题,看样例知规律。


    #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;
    int Ans[N],t=0;
    
    int main(){
    	n=input();
    	int l=1,r=n;
    	while(l<=r){
    		Ans[l++]=++t;
    		if(l>r) break;
    		Ans[r--]=++t;
    	}
    	for(int i=1;i<=n;i++) printf("%d%c",Ans[i],i==n? '
    ':' ');
    }
    

    C


    最好情况:普通随从破盾,剧毒随从杀怪。

    最坏情况:剧毒随从破盾。

    模拟即可。


    #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=1007;
    
    char s[N];
    
    int Solve1(int n,int a,int b,int c,int d){
    	int res=0;
    	for(int i=1;i<=n;i++){
    		if(s[i]=='1'){
    			if(c) c--,res++;
    			else if(d) d--,c++;
    			else if(a) a--,res++;
    			else if(b) b--,a++;
    		}else{
    			if(d) d--,c++;
    			else if(c) continue;
    			else if(b) b--,a++;
    			else if(a) continue;
    		}
    	}
    	return res;
    }
    
    int Solve2(int n,int a,int b,int c,int d){
    	int res=0;
    	for(int i=1;i<=n;i++){
    		if(s[i]=='1'){
    			if(d) d--,c++;
    			else if(c) c--,res++;
    			else if(b) b--,a++;
    			else if(a) a--,res++;
    		}else{
    			if(c) continue;
    			else if(d) d--,c++;
    			else if(a) continue;
    			else if(b) b--,a++;
    		}
    	}
    	return res;
    }
    
    int main(){
    	int T=input();
    	while(T--){
    		int n=input(),a=input(),b=input(),c=input(),d=input();
    		scanf("%s",s+1);
    		printf("%d %d
    ",Solve1(n,a,b,c,d),Solve2(n,a,b,c,d));
    	}
    }
    

    L


    BFS


    #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<int,int>
    #define fr first
    #define sc second
    #define mp make_pair
    
    const int N=107;
    
    int t[8][2]={{1,2},
    			 {1,-2},
    			 {-1,2},
    			 {-1,-2},
    			 {2,1},
    			 {2,-1},
    			 {-2,1},
    			 {-2,-1}
    			};
    int tt[8][2]={{0,1},
    			 {0,-1},
    			 {0,1},
    			 {0,-1},
    			 {1,0},
    			 {1,0},
    			 {-1,0},
    			 {-1,0}
    			};
    
    int Map[N][N];
    int Ans[N][N],vis[N][N];
    char s[N];
    queue <PII> q;
    
    int main(){
    	int n=input(),m=input();
    	PII sta;
    
    	for(int i=1;i<=n;i++){
    		scanf("%s",s+1);
    		for(int j=1;j<=m;j++){
    			if(s[j]=='X') Map[i][j]=1;
    			else Map[i][j]=0;
    
    			if(s[j]=='M') sta=mp(i,j);
    			Ans[i][j]=0x3f3f3f3f;
    		}
    	}
    
    	q.push(sta);
    	vis[sta.fr][sta.sc]=1;
    	Ans[sta.fr][sta.sc]=0;
    
    	while(!q.empty()){
    		int x=q.front().fr,y=q.front().sc;
    		vis[x][y]=0;
    		q.pop();
    		for(int i=0;i<=7;i++){
    			int tx=x+t[i][0],ty=y+t[i][1];
    			int ttx=x+tt[i][0],tty=y+tt[i][1];
    			if(1<=tx&&tx<=n&&1<=ty&&ty<=m&&Map[ttx][tty]==0&&Map[tx][ty]==0){
    				if(Ans[x][y]+1<Ans[tx][ty]){
    					Ans[tx][ty]=Ans[x][y]+1;
    					if(!vis[tx][ty]){
    						q.push(mp(tx,ty));
    						vis[tx][ty]=1;
    					}
    				}
    			}
    		}
    		
    	}
    
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			// cout<<Ans[i][j]<<endl;
    			printf("%d ",Ans[i][j]==0x3f3f3f3f? -1:Ans[i][j]);
    		}printf("
    ");
    	}
    }
    

    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=1e2+7,M=20;
    ll a[N][M],mx[N][M];
    
    int n,m,w;
    ll Ans[N];
    int num[N],vis[N],vvis[N][N];
    
    int main(){
    	n=input(),m=input(),w=input();
    	for(int i=1;i<=n;i++) Ans[i]=-1;
    	for(int i=1;i<=w;i++){
    		int x=input(),y=input(),c=input();
    		vis[x]=1;
    		if(c){
    			if(vvis[x][y]==0)num[y]++,vvis[x][y]=1;
    			a[x][y]=0;
    		}else{
    			a[x][y]++;
    			mx[x][y]=max(mx[x][y],a[x][y]);
    		}
    	}
    
    	for(int i=1;i<=n;i++){
    		int f=1;
    		for(int j=1;j<=m;j++)
    			if(!vvis[i][j]) f=0;
    		if(f) Ans[i]=0;
    	}
    
    	for(int i=1;i<=n;i++){
    		if(Ans[i]!=-1) continue;
    		Ans[i]=0;
    		if(vis[i]==0){
    			Ans[i]=998244353;
    			continue;
    		}
    		int f=1;
    		for(int j=1;j<=m;j++){
    			if(vvis[i][j])
    				f=0,Ans[i]+=mx[i][j]*mx[i][j];
    
    			if(!vvis[i][j]) Ans[i]+=2LL*mx[i][j]*mx[i][j];
    			if(vvis[i][j]==0&&num[j]){
    				Ans[i]+=20;
    				if(num[j]>=n/2) Ans[i]+=10;
    			}
    		}
    		if(f) Ans[i]=1000000;
    	}
    	for(int i=1;i<=n;i++)
    		printf("%lld
    ",Ans[i]);
    }
    

    F


    不难知道题目中所给的图是完全图,也就说对于任何一条边与图中任意一个非端点都可以组成一个三角形,然后就变成一个组合计数问题了。直接统计答案不太方便,我们可以统计不满足条件的方案然后容斥一下就解决了。


    #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=5007;
    #define pb push_back
    
    struct edge{
    	int u,v,w;
    };
    
    vector <edge> G;
    ll sum;
    ll cnt[N][2];
    
    int main(){
    	ll n=input();
    	sum=n*(n-1)*(n-2)/(3*2*1);
    	ll A=input(),B=input(),C=input(),P=input(),D=input();
    
    	for(int i=1;i<=n;i++){
    		for(int j=i+1;j<=n;j++){
    			ll tmp=(A*(i+j)*(i+j)+B*(i-j)*(i-j)+C)%P;
    			if(tmp>D){
    				cnt[i][1]++,cnt[j][1]++;
    				G.pb((edge){i,j,1});
    			}else{
    				cnt[i][0]++,cnt[j][0]++;
    				G.pb((edge){i,j,0});
    			}
    		}
    	}
    
    	ll Ans=0;
    
    	for(auto v:G){
    		if(v.w==1){
    			Ans+=cnt[v.u][0],
    			Ans+=cnt[v.v][0];
    		}else{
    			Ans+=cnt[v.u][1],
    			Ans+=cnt[v.v][1];
    		}
    	}
    
    	printf("%lld
    ",sum-Ans/4);
    }
    

    G


    贪心。


    #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=107;
    
    int a[N],Ans[N];
    
    int main(){
    	int T=input();
    	while(T--){
    		int n=input(),now=0,t=1;
    		for(int i=1;i<=n;i++){
    			a[i]=input();
    		}
    
    		while(now<n){
    			for(int i=n;i>=1;i--)
    				if(a[i]==t) Ans[i]=++now;
    			
    			for(int i=1;i<=n;i++){
    				if(a[i]==-1){a[i]=t,Ans[i]=++now;break;}
    				else if(a[i]==t) break;
    			}
    			t++;
    		}
    
    		for(int i=1;i<=n;i++){
    			printf("%d ",Ans[i]);
    		}printf("
    ");
    	}
    }
    

    H


    这个题看起来有一个奇奇怪怪的异或操作,看起来区间不再连续,实际上区间变为了(logn)个区间,所以只需要查询这(logn)个区间就行了。


    #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 pb push_back
    
    const int N=1e5+7;
    const ll mod=998244353;
    
    ll sum[N];
    int a[N];
    ll v[N],cnt=0;
    int n,q;
    
    ll ask(int x){
    	int pos=upper_bound(v+1,v+1+cnt,x)-v;
    	if(pos==1) return 0;
    	pos--;
    	ll res=sum[pos-1];
    	ll k=upper_bound(a,a+n,v[pos])-a;
    	res=(res+(x-v[pos]+1)*k%mod*k%mod)%mod;
    	return res;
    }
    
    ll ask(int l,int r){
    	return (ask(r)-ask(l-1))%mod;
    }
    
    ll query(int t,int x){
    	if(t<0) return 0;
    	int cur=0;ll res=0;
    	for(int i=30;i>=0;i--){
    		int u=(x>>i&1);
    		if(t>>i&1){
    			res+=ask(cur|(u<<i),(cur|(u<<i))+(1<<i)-1);
    			cur+=((1<<i)^(u<<i));
    		}else cur|=(u<<i);
    	}
    	res+=ask(cur,cur);
    	return res;
    }
    
    int main(){
    	n=input(),q=input();
    	for(int i=0;i<n;i++)
    		a[i]=input(),v[++cnt]=a[i];
    	sort(a,a+n);
    	sort(v+1,v+1+cnt);
    	cnt=unique(v+1,v+cnt+1)-v-1;
    
    	for(int i=1;i<cnt;i++){
    		ll k=upper_bound(a,a+n,v[i])-a;
    		sum[i]=(sum[i-1]+(v[i+1]-v[i])%mod*k%mod*k%mod)%mod;
    	}
    
    	for(int i=1;i<=q;i++){
    		int l=input(),r=input(),x=input();
    		ll Ans=((query(r,x)-query(l-1,x))%mod+mod)%mod;
    		printf("%lld
    ",Ans);
    	}
    
    }
    

    I


    最后的答案肯定是若干个连续的区域最大值,我们不妨借用背包问题的思想来确定这些区间的最大值和长度。


    #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=57;
    
    int n,a[N],dp[N][N];
    
    int main(){
    	int T=input();
    	while(T--){
    		memset(dp,0,sizeof(dp));
    		n=input();
    		for(int i=1;i<=n;i++)
    			a[i]=input();
    
    		for(int i=1;i<=n;i++){
    			int mx=a[i];
    			for(int j=i-1;j>=0;j--){
    				int c=(i-j)/2;
    				for(int k=0;k+c<=i;k++){
    					dp[i][k+c]=max(dp[i][k+c],dp[j][k]+mx*(i-j));
    				}
    				mx=max(a[j],mx);
    			}
    		}
    
    		for(int i=1;i<=n;i++){
    			printf("%lld%c",dp[n][i],i==n?'
    ':' ');
    		}
    	}
    }
    

  • 相关阅读:
    398. Random Pick Index
    739. Daily Temperatures
    779. K-th Symbol in Grammar
    698. Partition to K Equal Sum Subsets
    783. Minimum Distance Between BST Nodes
    asp.netcore 深入了解配置文件加载过程
    啥叫K8s?啥是k8s?
    Asp.NetCore轻松学-实现一个轻量级高可复用的RabbitMQ客户端
    Asp.Net Core 轻松学-一行代码搞定文件上传
    目录---Asp.NETCore轻松学系列【目录】
  • 原文地址:https://www.cnblogs.com/-aether/p/12396631.html
Copyright © 2011-2022 走看看