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

    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=1007;
    
    ll a[N][N];
    ll Ans[N];
    
    int main(){
    	int n=input();
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			a[i][j]=input();
    
    	if(n==2){
    		printf("%lld %lld
    ",a[1][2]/2,a[1][2]-a[1][2]/2);
    		exit(0);
    	}
    	for(int i=2;i<=n-1;i++){
    		Ans[i]=(a[i-1][i]+a[i][i+1]-a[i-1][i+1])/2;
    	}
    	Ans[1]=a[1][2]-Ans[2];
    	Ans[n]=a[n-1][n]-Ans[n-1];
    	for(int i=1;i<=n;i++){
    		printf("%lld ",Ans[i]);
    	}
    }
    

    E


    每次对答案产生贡献只有最右下角的棋子才会对答案产生贡献(类似博弈论的推理),那么只要统计当前位置被翻转了多少次,边维护前缀和边算答案就行了。


    #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=507;
    
    int n,m;
    char s[507];
    int a[N][N];
    int d[N][N];
    
    int main(){
    	int T=input();
    	while(T--){
    		n=input(),m=input();
    		for(int i=1;i<=n;i++){
    			scanf("%s",s+1);
    			for(int j=1;j<=m;j++){
    				a[i][j]=s[j]=='0'? 0:1;
    			}
    		}
    
    		for(int i=1;i<=n+5;i++)
    			for(int j=1;j<=m+5;j++)
    				d[i][j]=0;
    
    		int cnt=0;
    		for(int i=n;i>=1;i--){
    			for(int j=m;j>=1;j--){
    				d[i][j]+=d[i+1][j]+d[i][j+1]-d[i+1][j+1];
    				if((d[i][j]+a[i][j])%2==1)
    					d[i][j]++,cnt++;
    			}
    		}
    
    
    		if(cnt%2) printf("call
    ");
    		else printf("aoligei
    ");
    	}
    }
    

    G


    答案显然是:到所有标记点的距离*2-到最远的点的距离。树dp维护这个式子,就可以做出来了。


    #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,ll>
    #define fr first
    #define sc second
    #define mp make_pair
    #define pb push_back
    
    const int N=5e5+7;
    
    ll dis1[N],dis2[N],sum[N],siz[N];
    vector<PII> G[N];
    int n,k;
    
    void Ins(int u,int v,ll w){
    	G[u].pb(mp(v,w));
    	G[v].pb(mp(u,w));
    }
    
    void modify(int dis,int u){
    	if(dis>dis1[u]) dis2[u]=dis1[u],dis1[u]=dis;
    	else if(dis>dis2[u]) dis2[u]=dis;
    }
    
    void dfs1(int u,int fa){
    	for(auto vv:G[u]){
    		ll v=vv.fr,w=vv.sc;
    		if(v==fa) continue;
    		dfs1(v,u);
    		siz[u]+=siz[v];
    		if(siz[v]){
    			sum[u]+=2*w+sum[v];
    			modify(dis1[v]+w,u);
    		}
    	}
    }
    
    void dfs2(int u,int fa){
    	for(auto vv:G[u]){
    		ll v=vv.fr,w=vv.sc;
    		if(v==fa) continue;
    		sum[v]=sum[u]-2*w*(siz[v]==k)+2*w*(siz[v]==0);
    		if(dis1[u]==dis1[v]+w){
    			if(siz[u]-siz[v]!=0){
    				modify(dis2[u]+w,v);
    			}
    		}else modify(dis1[u]+w,v);
    		dfs2(v,u);
    	}
    }
    
    int main(){
    	n=input(),k=input();
    	for(int i=1;i<n;i++){
    		int u=input(),v=input(),w=input();
    		Ins(u,v,w);
    	}
    
    	for(int i=1;i<=k;i++){
    		int x=input();
    		siz[x]=1;
    	}
    
    	dfs1(1,0),dfs2(1,0);
    
    	for(int i=1;i<=n;i++){
    		printf("%lld
    ",sum[i]-dis1[i]);
    	}
    }
    

    C


    转换为染色问题,相当于求给图中每一个点染色,有边相连的点颜色不能相同,最少需要多少种颜色,而最多的路径便是颜色的数量-1。


    #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=20;
    
    int G[N][N],color[N];
    int Ans=0x3f3f3f3f;
    int cnt=0;
    int n,m;
    
    bool check(int u,int c){
    	for(int i=1;i<=n;i++){
    		if(G[u][i]&&color[i]==c){
    			return 0;
    		}
    	}
    	return 1;
    }
    
    void dfs(int dep){
    	if(cnt>=Ans) return;
    	if(dep>n){Ans=min(cnt,Ans);return;}
    	for(int i=1;i<=cnt+1;i++){
    		if(check(dep,i)){
    			color[dep]=i;
    			if(i>cnt){
    				cnt++;
    				dfs(dep+1);
    				cnt--;
    			}else dfs(dep+1);
    			color[dep]=0;
    		}
    	}
    }
    
    int main(){
    	n=input(),m=input();
    	for(int i=1;i<=m;i++){
    		int u=input(),v=input();
    		G[u][v]=G[v][u]=1;
    	}
    	dfs(1);
    	printf("%d
    ",Ans-1);
    }
    
  • 相关阅读:
    bzoj3932 [CQOI2015]任务查询系统
    bzoj1901 Zju2112 Dynamic Rankings
    bzoj3524 [Poi2014]Couriers/2223 [Coci 2009]PATULJCI
    bzoj1529 [POI2005]ska Piggy banks
    bzoj1552 [Cerc2007]robotic sort
    bzoj2208 [Jsoi2010]连通数
    2016NOI冬令营day5
    A1035 Password (20)(20 分)
    1048 数字加密(20 分)
    福尔摩斯的约会
  • 原文地址:https://www.cnblogs.com/-aether/p/12362051.html
Copyright © 2011-2022 走看看