topcoder srm 350 div1

problem1 link

满足$a^{b}leq5000000,b>1$的数字不多,有2000多个,直接暴力计算能组成哪些数字即可。

import java.util.*;
import java.math.*;
import static java.lang.Math.*;

public class SumsOfPerfectPowers {
	
	public int howMany(int lowerBound,int upperBound) {
		boolean[] a=new boolean[upperBound+1];
		a[0]=true;
		if(upperBound>=1) {
			a[1]=true;
		}

		for(int i=2;i*i<=upperBound;++i) {
			if(a[i]) {
				continue;
			}
			int k=i*i;
			while(k<=upperBound) {
				a[k]=true;
				if(k>upperBound/i) {
					break;
				}
				k=k*i;
			}
		}
		int num=0;
		for(int i=1;i<=upperBound;++i) {
			if(a[i]) {
				++num;
			}
		}
		int[] b=new int[num];
		num=0;
		for(int i=1;i<=upperBound;++i) {
			if(a[i]) {
				b[num++]=i;
			}
		}
		for(int i=0;i<b.length;++i) {
			for(int j=i;j<b.length;++j) {
				if(b[i]+b[j]>upperBound) {
					break;
				}
				a[b[i]+b[j]]=true;
			}
		}
		num=0;
		for(int i=lowerBound;i<=upperBound;++i) {
			if(a[i]) {
				++num;
			}
		}
		return num;
	}
}

  

problem2 link

计算出每个点的值,bfs即可。长度大于顶点$n$时说明有环。

import java.util.*;
import java.math.*;
import static java.lang.Math.*;

public class StarsInGraphs {

	public int starryPaths(String[] adjacencyMatrix,int C) {
		final int n=adjacencyMatrix.length;
		List<List> g=new ArrayList<>();
		for(int i=0;i<n;++i) {
			g.add(new ArrayList<>());
		}
		long[] d=new long[n];
		for(int i=0;i<n;++i) {
			for(int j=0;j<n;++j) {
				if(adjacencyMatrix[i].charAt(j)=='1') {
					g.get(i).add(j);
					++d[i];
				}
			}
		}
		for(int i=0;i<n;++i) {
			d[i]=(1l<<d[i])-1-d[i]-d[i]*(d[i]-1)/2;
		}
		int[] f=new int[n];
		boolean[] inq=new boolean[n];
		Queue<Integer> queue=new LinkedList<>();
		for(int i=0;i<n;++i) {
			if(1<=d[i]&&d[i]<=C) {
				f[i]=1;
				inq[i]=true;
				queue.offer(i);
			}
		}
		while(!queue.isEmpty()) {
			int u=queue.poll();
			inq[u]=false;
			for(int i=0;i<g.get(u).size();++i) {
				int v=(int)g.get(u).get(i);
				if(d[u]<=d[v]&&d[v]<=C&&f[u]+1>f[v]) {
					f[v]=f[u]+1;
					if(f[v]>n) {
						return -1;
					}
					if(!inq[v]) {
						inq[v]=true;
						queue.offer(v);
					}
				}
			}
		}
		int result=0;
		for(int i=0;i<n;++i) {
			result=Math.max(result,f[i]);
		}
		return result;
	}


}

  

problem3 link

求出所有交点,那么就是一个图。每条边看作两条有向边。对于每个封闭图形(必是凸包)逆时针找它的每条边。

import java.util.*;
import java.math.*;
import static java.lang.Math.*;

public class PlaneDivision {



	static class Rational {
		public BigInteger x;
		public BigInteger y;
		public int sign;

		public Rational copy() {
			return new Rational(new BigInteger(x.toString()),new BigInteger(y.toString()),sign);
		}

		public Rational() {

		}
		public Rational(BigInteger _x,BigInteger _y,int _sign) {
			x=_x;
			y=_y;
			sign=_sign;
			simple();
		}

		public Rational(long t) {
			x=new BigInteger(Long.toString(t));
			y=BigInteger.ONE;
			sign=1;
			simple();
		}

		public boolean equals(Rational a) {
			if(x.equals(BigInteger.ZERO)) {
				return a.x.equals(BigInteger.ZERO);
			}
			if(a.x.equals(BigInteger.ZERO)) {
				return false;
			}
			return sign==a.sign&&x.equals(a.x)&&y.equals(a.y);
		}

		private Rational simple() {
			if(x.equals(BigInteger.ZERO)) {
				sign=1;
				y=BigInteger.ONE;
			}
			else {
				if(x.compareTo(BigInteger.ZERO)<0) {
					x=x.negate();
					sign=-sign;
				}
				BigInteger t=x.gcd(y);

				if(!t.equals(BigInteger.ONE)) {
					x=x.divide(t);
					y=y.divide(t);
				}

			}
			return this;
		}

		public Rational add(Rational a) {
			if(a.x.equals(BigInteger.ZERO)) {
				return copy();
			}
			if(x.equals(BigInteger.ZERO)) {
				return a.copy();
			}


			BigInteger p=y.multiply(a.y);
			BigInteger x1=x.multiply(a.y);
			BigInteger x2=a.x.multiply(y);

			Rational result=new Rational();
			result.y=p;

			if(sign==1) {
				if(a.sign==1) {
					result.x=x1.add(x2);
					result.sign=1;
				}
				else {
					result.x=x1.subtract(x2);
					result.sign=1;
				}
			}
			else {
				if(a.sign==1) {
					result.x=x2.subtract(x1);
					result.sign=1;
				}
				else {
					result.x=x1.add(x2);
					result.sign=-1;
				}
			}
			return result.simple();
		}

		public Rational substract(Rational a) {
			return add(new Rational(a.x,a.y,-a.sign));
		}

		public Rational multiply(Rational a) {
			if(x.equals(BigInteger.ZERO)) {
				return new Rational(0);
			}
			if(a.x.equals(BigInteger.ZERO)) {
				return new Rational(0);
			}

			Rational result=new Rational();
			result.x=x.multiply(a.x);
			result.y=y.multiply(a.y);
			result.sign=sign*a.sign;
			return result.simple();
		}
		public Rational divide(Rational a) {
			if(x.equals(BigInteger.ZERO)) {
				return new Rational(0);
			}
			return multiply(new Rational(a.y,a.x,a.sign));
		}

		public boolean lessThan(Rational a) {

			if(a.x.equals(BigInteger.ZERO)) {
				if(x.equals(BigInteger.ZERO)) {
					return false;
				}
				return sign==-1?true:false;
			}
			if(x.equals(BigInteger.ZERO)) {
				return a.sign==1?true:false;
			}
			if(sign<a.sign){
				return true;
			}
			if(a.sign<sign) {
				return false;
			}

			if(sign==1) {
				return x.multiply(a.y).compareTo(a.x.multiply(y))<0;
			}
			else {
				return x.multiply(a.y).compareTo(a.x.multiply(y))>0;
			}
		}



		public double toDouble() {
			return 1.0*Double.valueOf(x.toString())/Double.valueOf(y.toString())*sign;
		}

		public String toString() {
			return Double.toString(toDouble());
		}
	}

	static int DB(Rational x)
	{
		if(x.x.equals(BigInteger.ZERO)) {
			return 0;
		}
		return x.sign;
	}


	static class point implements Comparable
	{
		public Rational x;
		public Rational y;

		public point(){}
		public point(Rational _x,Rational _y) {
			this.x=_x.copy();
			this.y=_y.copy();
		}



		public point add(point a)
		{
			return new point(x.add(a.x),y.add(a.y));
		}

		public point substract(point a)
		{
			return new point(x.substract(a.x),y.substract(a.y));
		}

		public Rational crossMultiply(point a)
		{
			return x.multiply(a.y).substract(y.multiply(a.x));
		}

		public point multiply(Rational t)
		{
			return new point(x.multiply(t),y.multiply(t));
		}

		public Rational dotMultiply(point a)
		{
			return x.multiply(a.x).add(y.multiply(a.y));
		}



		public double getAng(point a)
		{
			return Math.atan2(crossMultiply(a).toDouble(),dotMultiply(a).toDouble());
		}


		public boolean equals(point a)
		{
			return x.equals(a.x)&&y.equals(a.y);
		}

		public point divide(Rational a) {
			return new point(x.divide(a),y.divide(a));
		}


		@Override
		public int compareTo(Object e) {
			point t=(point)e;
			if(DB(x.substract(t.x))!=0) {
				return x.lessThan(t.x)?-1:1;
			}
			if(DB(y.substract(t.y))==0) {
				return 0;
			}
			return y.lessThan(t.y)?-1:1;
		}

		public String toString() {
			return x.toString()+","+y.toString();
		}


	}

	static class pair {
		public int first;
		public int second;

		public pair() {}
		public pair(int first,int second) {
			this.first=first;
			this.second=second;
		}
	}

	static final int N=85;

	point[][] L=null;
	List<List<point>> G=null;
	List<point> p=null;

	int m;
	point x,y;

	List<List<pair>> g=null;

	boolean[] visit=null;
	int n;



	void init() {
		L=new point[N][];
		for(int i=0;i<N;++i) {
			L[i]=new point[2];
		}
		G=new ArrayList<>();
		for(int i=0;i<N;++i) {
			G.add(new ArrayList<>());
		}
		p=new ArrayList<>();
		g=new ArrayList<>();
		for(int i=0;i<N*N*N;++i) {
			g.add(new ArrayList<>());
		}
		visit=new boolean[N*N*N];
	}

	boolean isParal(point a,point b,point p,point q)
	{
		Rational x=(b.x.substract(a.x)).multiply(q.y.substract(p.y));
		Rational y=(b.y.substract(a.y)).multiply(q.x.substract(p.x));
		return DB(x.substract(y))==0;
	}

	point getCross(point a,point b,point p,point q)
	{
		Rational s1=(a.substract(p)).crossMultiply(b.substract(p));
		Rational s2=(b.substract(q)).crossMultiply(a.substract(q));
		return (p.multiply(s2).add(q.multiply(s1))).divide(s1.add(s2));
	}


	Rational cross(point a,point b,point p)
	{
		return (b.substract(a)).crossMultiply(p.substract(a));
	}


	class MyComparator implements Comparator {
		public int compare(Object o1,Object o2) {
			pair A=(pair)o1;
			pair B=(pair)o2;
			point a=p.get(A.first);
			point b=p.get(B.first);



			Rational xx=cross(x,y,a);
			Rational yy=cross(x,y,b);
			if(DB(xx)!=DB(yy)) {
				return DB(xx)>DB(yy)?-1:1;
			}


			double dx=a.substract(y).getAng(x.substract(y));
			double dy=b.substract(y).getAng(x.substract(y));

			return dx<dy?-1:1;
		}
	}

	int getindex(point t) {
		for(int i=0;i<p.size();++i) {
			if(p.get(i).equals(t)) {
				return i;
			}
		}
		assert false;
		return -1;
	}


	void build()
	{
		int x=0;
		for(int i=1;i<=n;++i)
		{
			for(int j=0;j+1<G.get(i).size();++j)
			{
				int k=getindex(G.get(i).get(j));
				int t=getindex(G.get(i).get(j+1));

				if(k==t) {
					continue;
				}
				g.get(k).add(new pair(t,++x));
				g.get(t).add(new pair(k,++x));
			}
		}
	}


	int result;

	void DFS(int cur,int pre,int t)
	{
		if(cur==t) {
			++result;
			return;
		}
		x=p.get(pre);
		y=p.get(cur);
		Collections.sort(g.get(cur),new MyComparator());

		for(int i=0;i<g.get(cur).size();++i)
		{
			int j=g.get(cur).get(i).first;
			int k=g.get(cur).get(i).second;
			if(j==pre||visit[k]) {
				continue;
			}
			if(DB(cross(p.get(pre),p.get(cur),p.get(j)))<=0) {
				return;
			}
			visit[k]=true;
			DFS(j,cur,t);
			return;
		}
	}

	int cal()
	{
		result=0;
		for(int i=0;i<m;++i)
		{
			for(int j=0;j<g.get(i).size();++j)
			{
				int k=g.get(i).get(j).first;
				int t=g.get(i).get(j).second;
				if(visit[t]||j!=0&&g.get(i).get(j-1).first==k) {
					continue;
				}
				visit[t]=true;
				DFS(k,i,i);
			}
		}
		return result;
	}

	
	public int howManyFiniteParts(int[] x1, int[] y1, int[] x2, int[] y2) {

		init();

		n=x1.length;

		for(int i=1;i<=n;++i)
		{
			L[i][0] = new point(new Rational(x1[i-1]),new Rational(y1[i-1]));
			L[i][1] = new point(new Rational(x2[i-1]),new Rational(y2[i-1]));

			for(int j=1;j<i;++j)
			{
				if(isParal(L[j][0],L[j][1],L[i][0],L[i][1])) {
					continue;
				}
				point temp=getCross(L[j][0],L[j][1],L[i][0],L[i][1]);
				int k=-1;
				for(k=0;k<G.get(i).size();k++) {
					point t=G.get(i).get(k);
					if(t.equals(temp)) {
						break;
					}
				}
				if(k>=G.get(i).size())  {
					G.get(i).add(temp);
				}
				for(k=0;k<G.get(j).size();k++) {
					point t=G.get(j).get(k);
					if(t.equals(temp)) {
						break;
					}
				}
				if(k>=G.get(j).size()) {
					G.get(j).add(temp);
				}
				p.add(temp);
			}
		}

		Collections.sort(p);

		if(p.size()==0) {
			m=0;
		}
		else {
			m=1;
			for(int i=1;i<p.size();++i) {
				if(!p.get(m-1).equals(p.get(i))) {
					p.set(m,p.get(i));
					++m;
				}
			}
		}

		for(int i=1;i<=n;++i) {
			Collections.sort(G.get(i));
		}
		build();
		return cal();
	}
}

  

原文地址:https://www.cnblogs.com/jianglangcaijin/p/7506882.html