zoukankan      html  css  js  c++  java
  • 【题解】[USACO13FEB]Tractor S

    题目戳我

    ( ext{Solution:})

    好久没写啥(dfs)了,借这个题整理下细节。

    观察到答案具有二分性,所以先求出其差的最大最小值,(log val)的复杂度不成问题。

    考虑如何(check:)

    考虑一个(dfs)预处理当前点为((i,j),)高度为(k)所能到达的所有点。这一步是(n^2)的复杂度。注意判断是否出界的时候符号不要打反,以及这题所谓高度差是在绝对值意义上的。

    遍历变量时不要重名。之所以每次不需要清空(vis)是因为每次(dfs)都会保证找齐一个点所能到达的所有点。

    于是,这题可以在(O(n^2log m))的复杂度完成。

    还有一个想法是求出原树的最小生成树后处理出(siz)和子树的最大差。然后可以((n^2log n^2))实现这题。

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=5e5+10;
    int a[501][501],n;
    const int dx[4]={1,0,-1,0};
    const int dy[4]={0,1,0,-1};
    int L,R,ans,vis[501][501];
    int dfs(int x,int y,int kk){
    	int cnt=1;
    	vis[x][y]=1;
    	for(int k=0;k<4;++k){
    		int nx=x+dx[k],ny=y+dy[k];
    		if(nx<1||ny<1||nx>n||ny>n||vis[nx][ny]||abs(a[x][y]-a[nx][ny])>kk)continue;
    		cnt+=dfs(nx,ny,kk);
    	}
    	return cnt;
    }
    bool check(int k){
    	memset(vis,0,sizeof vis);
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j){
    			if(vis[i][j])continue;
    			int C=dfs(i,j,k);
    			if(C*2>=n*n)return true;
    		}
    	return false;
    }
    int main(){
    	scanf("%d",&n);
    	L=(1<<30);R=-L;
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j)
    			scanf("%d",&a[i][j]);
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			for(int k=0;k<4;++k){
    				int x=i+dx[k],y=j+dy[k];
    				R=max(R,a[i][j]-a[x][y]);
    				L=min(L,a[i][j]-a[x][y]);
    			}
    		}
    	}
    	while(L<=R){
    		int mid=L+R>>1;
    		if(check(mid))ans=mid,R=mid-1;
    		else L=mid+1; 
    	}
    	printf("%d
    ",ans);
    	return 0;
    } 
    
  • 相关阅读:
    好用的软件记录
    微信小程序 设计理念指南
    开启Python之路
    升级到iOS9之后的相关适配
    ARC模式下的内存泄露问题
    Git 源代码管理工具
    SVN版本控制系统
    单例 singleton
    双击改变图片大小和多点触摸改变图片大小
    循环引用 -- id 为什么是 assign 而不是 retain
  • 原文地址:https://www.cnblogs.com/h-lka/p/13686545.html
Copyright © 2011-2022 走看看