• topcoder srm 410 div1


    problem1 link

    不包含$gridConnections$ 的联通块一定是连在所有包含$gridConnections$的联通块中最大的那一块上。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class AddElectricalWires {
    
    	static class UnionSet {
    		public int[] father=null;
    		public int[] size=null;
    		public int[] edges=null;
    
    		public UnionSet(int n) {
    			father=new int[n];
    			size=new int[n];
    			edges=new int[n];
    			for(int i=0;i<n;++i) {
    				father[i]=i;
    				size[i]=1;
    			}
    		}
    
    		public int getFather(int x) {
    			if(father[x]==x) {
    				return x;
    			}
    			return father[x]=getFather(father[x]);
    		}
    		public UnionSet merge(int x,int y) {
    			int fx=getFather(x);
    			int fy=getFather(y);
    			if(fx!=fy) {
    				father[fx]=fy;
    				size[fy]+=size[fx];
    				edges[fy]+=edges[fx]+1;
    			}
    			else {
    				edges[fy]+=1;
    			}
    			return this;
    		}
    	}
    
    	public int maxNewWires(String[] wires,int[] gridConnections) {
    		final int n=wires.length;
    		UnionSet unionSet=new UnionSet(n);
    		for(int i=0;i<n;++i) {
    			for(int j=i+1;j<n;++j) {
    				if(wires[i].charAt(j)=='1') {
    					unionSet.merge(i,j);
    				}
    			}
    		}
    
    
    		int result=0;
    		long visited=0;
    		int maxSize=0;
    		for(int i=0;i<gridConnections.length;++i) {
    			int t=gridConnections[i];
    			int ft=unionSet.getFather(t);
    			int sz=unionSet.size[ft];
    			result+=sz*(sz-1)/2-unionSet.edges[ft];
    			visited|=1l<<ft;
    			if(sz>maxSize) {
    				maxSize=sz;
    			}
    		}
    		for(int i=0;i<n;++i) {
    			if(i==unionSet.getFather(i)&&(0==(visited&(1l<<i)))) {
    				int sz=unionSet.size[i];
    				result+=sz*(sz-1)/2-unionSet.edges[i];
    				result+=sz*maxSize;
    				maxSize+=sz;
    			}
    		}
    		return result;
    	}
    }
    

      

    problem2 link

    每个$base$的选择一定是$addresses[i]$或者$addresses[i]-k+1$。这样进行动态规划即可。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class ContiguousCache {
    	
    	public long minimumReads(int n, int k, int[] addresses) {
    		List<Integer> list=new ArrayList<>();
    		final int m=addresses.length;
    		for(int i=0;i<m;++i) {
    			final int t=addresses[i];
    			if(t-k+1>=0) {
    				list.add(t-k+1);
    			}
    			if(t<=n-k) {
    				list.add(t);
    			}
    			else {
    				list.add(n-k);
    			}
    
    		}
    		int[] a=unique(list);
    
    		final int p=a.length;
    		long[][] f=new long[m][p];
    		for(int i=0;i<m;++i) {
    			for(int j=0;j<p;++j) {
    				f[i][j]=-1;
    			}
    		}
    		for(int i=0;i<p;++i){
    			if(a[i]<=addresses[0]&&addresses[0]<a[i]+k) {
    				f[0][i]=Math.min(n,a[i]+k-1)-a[i]+1;
    			}
    		}
    
    
    		for(int i=1;i<m;++i) {
    			final int r=addresses[i];
    			for(int j=0;j<p;++j) {
    				if(f[i-1][j]==-1) {
    					continue;
    				}
    
    				for(int t=0;t<p;++t) {
    
    					if(a[t]<=r&&r<a[t]+k) {
    						long cost=f[i-1][j]+calCost(a[j],a[t],k);
    						if(f[i][t]==-1||f[i][t]>cost) {
    							f[i][t]=cost;
    						}
    					}
    				}
    
    			}
    		}
    
    
    		long result=-1;
    		for(int i=0;i<p;++i) {
    			if(f[m-1][i]==-1) {
    				continue;
    			}
    			if(result==-1||result>f[m-1][i]) {
    				result=f[m-1][i];
    			}
    		}
    		return result;
    	}
    
    
    	int calCost(int p1,int p2,int k) {
    		if(p1<p2) {
    			if(p1+k<=p2) {
    				return k;
    			}
    			return p2-p1;
    		}
    		else if(p1==p2) {
    			return 0;
    		}
    		else {
    			if(p2+k<=p1) {
    				return k;
    			}
    			return p1-p2;
    		}
    	}
    
    	int[] unique(List<Integer> list) {
    		Collections.sort(list);
    		int c=1;
    		int pre=0;
    		for(int i=1;i<list.size();++i) {
    			if(list.get(i)==list.get(pre)) {
    				continue;
    			}
    			++c;
    			pre=i;
    		}
    		int[] a=new int[c];
    		a[0]=list.get(0);
    		c=1;
    		for(int i=1;i<list.size();++i) {
    			if(a[c-1]!=list.get(i)) {
    				a[c++]=list.get(i);
    			}
    		}
    		return a;
    	}
    }
    

      

    problem3 link

    首先进行梯形剖分。对于变形每条边$p,q$,分别向$x$轴做垂线,该边与垂线以及$x$轴可以组成一个梯形。对于$n$条边$n$个梯形来说,注意有的取正值有的取负值加起来就能得到整个内部的点个数。

    对于一个梯形来说,内部点可以用公式$sum_{i=0}^{n-1}left lfloor frac{a+di}{m} ight floor$来进行计算。

    这里可以认为$0leq a < m,0<b<m$,否则可以直接提出到外面进行计算。

    对于某个$i$,$left lfloor frac{a+di}{m} ight floor$的值可以看作垂线$(i,0),(i,a+di)$与水平线$y=km$的交点个数,$1leq k leq left lfloor frac{a+di}{m} ight floor$

    到这里可以换个角度计算。对于每条水平线有多少垂线与其有交点。按照这个思路,可转化计算的公式:

    $sum_{i=0}^{n-1}left lfloor frac{a+di}{m} ight floor$=$sum_{k=0}^{L-1}left lfloor frac{(a+dn)mod(m)+mk}{d} ight floor$,其中$L=left lfloor frac{a+dn}{m} ight floor$

    中间的推导就不写了。

    等号后面的式子跟前面形式类似,所以可以继续转化,每次求和项都在减少。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class WifiPlanet {
    	
    	public long routersNeeded(int[] x, int[] y, int denom) {
    		final int n=x.length;
    		long result=0;
    		for(int i=0;i<n;++i) {
    			result+=cal(x[i],y[i],x[(i+1)%n],y[(i+1)%n],denom);
    		}
    		if(result<0) {
    			result=-result;
    		}
    		return result;
    	}
    
    	long cal(long x1,long y1,long x2,long y2,long m) {
    		if(x1==x2) {
    			return 0;
    		}
    		if(x1>x2) {
    			return -cal(x2,y2,x1,y1,m);
    		}
    		long L=(x1+m-1)/m*m;
    		long R=(x2-1)/m*m;
    		long n=(R-L)/m+1;
    		return dfs((y1*(x2-x1)+(y2-y1)*(L-x1))/m,y2-y1,n,x2-x1);
    	}
    
    	long dfs(long a,long d,long n,long m) {
    		if(n==0) {
    			return 0;
    		}
    		if(d==0) {
    			return a/m*n;
    		}
    		if(d<0) {
    			return dfs(a+d*(n-1),-d,n,m);
    		}
    		if(a>=m) {
    			return dfs(a%m,d,n,m)+a/m*n;
    		}
    		if(d>=m) {
    			return dfs(a,d%m,n,m)+(d/m)*n*(n-1)/2;
    		}
    		return dfs((a+n*d)%m,m,(a+n*d)/m,d);
    	}
    
    }
    

      

  • 相关阅读:
    show()的几种方法
    sql的交叉连接,内连接,左外连接,右外连接,全外连接总结
    MySQL数据库引擎介绍、区别、创建和性能测试的深入分析
    RedHat9通过Host-only配置网络连接
    解决Struts2.2.20版本的标签不支持style属性的问题
    SQL查询数据库中所有含有某一列的所有表
    简单工厂模式
    vc常用类总结(转载)
    嵌入式程序员应知道的0x10个C语言Tips
    C语言位操作
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/7538124.html
Copyright © 2020-2023  润新知