CCF 201812-3 CIDR合并 (java实现).

       在网上找了很多关于这个题的代码,发现大多数是c++写的,java实现的却寥寥无几,也没有找到java实现的满分代码,就自己写了两种方式的代码,但结果都不理想,估计是java运行速度太慢了,也可能是更好的方法没想到,我用两种方式实现的结果都是运行超时、90分,估计不超时的话就满分了;

      下面是问题描述和实现代码,作为备忘录,之后写出满分代码再修改。

 

问题描述


输入样例

2
1
2

输出样例

1.0.0.0/8
2.0.0.0/8

输入样例

2
10/9
10.128/9

输出样例

10.0.0.0/8

输入样例

2
0/1
128/1

输出样例

0.0.0.0/0

java实现代码(90分  运行超时  方法一)


import java.util.*;

class IPpref{
	public long ip;
	public int len;
	public IPpref(long ip,int len) {
		this.ip=ip;
		this.len=len;
	}
}

public class Main {

	public static void main(String[] args) {
		
		Scanner reader=new Scanner(System.in);
		int n=Integer.parseInt(reader.nextLine());
		List<IPpref> a=new ArrayList<IPpref>(); 
		for(int d=0;d<n;d++) {
			
			String ip=reader.nextLine();
			
			long Ip=0;   //实际ip值
			int len=0;   //掩码长度
			int j=1;
			int index=ip.indexOf("/");
			if(index!=-1) {
				
				String[] b= ip.split("/");
				len=Integer.parseInt(b[1]);
				String str= b[0];
				if(str.indexOf(".")!=-1) b=str.split("\\.");
				else b=new String[] {str};
				
				j=1<<(8*(4-b.length));
				for(int i=b.length-1;i>=0;i--) {
					Ip+=Long.parseLong(b[i])*j;
					j<<=8;
				}
			}else {
				String[] b= new String[]{ip};
				if(ip.indexOf(".")!=-1) b=ip.split("\\.");
				j=1<<(8*(4-b.length));
				len=b.length*8;
				for(int i=b.length-1;i>=0;i--) {
					Ip+=Long.parseLong(b[i])*j;
					j<<=8;
				}
			}
			IPpref ipPref=new IPpref(Ip,len);
			int m=0;
			int n1=a.size()-1;
			while(true){
				
				if(m>n1) {
					a.add(m, ipPref);
					break;
				}
				if(m==n1) {
					if(a.get(m).ip>Ip) a.add(m, ipPref);
					else if(a.get(m).ip<Ip) a.add(m+1,ipPref);
					else if(a.get(m).len>len) a.set(m, ipPref);
					break;
				}
				
				int k=(m+n1)/2;
				if(a.get(k).ip>Ip) n1=k-1;
				else if(a.get(k).ip<Ip) m=k+1;
				else if(a.get(k).len>len) {
					a.set(k, ipPref);
					break;
				}else break;
			}
		}
		int size=a.size()-1;
		int max;
		long f,L,mask;
		for(int k=0;k<size;) {
			max=32-Math.min(a.get(k).len, a.get(k+1).len);
			mask=-1L<<max;
			f=a.get(k).ip&mask;
			L=a.get(k+1).ip&mask;
			if(f==L) {
				a.set(k, new IPpref(f,32-max));
				a.remove(k+1);
				size--;
				continue;
			}
			k++;
		}
		
		for(int k=0;k<size;) {
			if(a.get(k).len!=a.get(k+1).len) {
				k++;
				continue;
			}
			
			max=33-a.get(k).len;
			mask=-1L<<max;
			f=a.get(k).ip&mask;
			L=a.get(k+1).ip&mask;
			if(f==L) {
				a.set(k, new IPpref(f,32-max));
				a.remove(k+1);
				size--;
				if(k!=0) k--;
				continue;
			}
			k++;
		}
		
		reader.close();
		long s,a0,a1,a2,a3;
		String str="";
		for(IPpref ip:a) {
			s=ip.ip>>8;
			a0=ip.ip%256;
			a1=s%256;
			s>>=8;
			a2=s%256;
			s>>=8;
			a3=s%256;
			str=a3+"."+a2+"."+a1+"."+a0+"/"+ip.len;
			System.out.println(str);
		}

	}
}

方式二(90分  运行超时)

import java.util.*;

class IPpref{
	public int[] ip;
	public int len;
	public IPpref(int[] ip,int len) {
		this.ip=ip;
		this.len=len;
	}
}

public class Main {

	public static void main(String[] args) {
		
		Scanner reader=new Scanner(System.in);
		int n=Integer.parseInt(reader.nextLine());
		List<IPpref> a=new ArrayList<IPpref>(); 
		
		for(int d=0;d<n;d++) {
			String ip=reader.nextLine();
			int[] Ip=new int[4];   //实际ip值
			int len=0;   //掩码长度
			int index=ip.indexOf("/");
			if(index!=-1) {
				String[] b= ip.split("/");
				len=Integer.parseInt(b[1]);
				String str= b[0];
				if(str.indexOf(".")!=-1) b=str.split("\\.");
				else b=new String[] {str};
				
				for(int i=0;i<b.length;i++)  Ip[i]=Integer.parseInt(b[i]);
				for(int i=b.length;i<4;i++)  Ip[i]=0;
			}else {
				String[] b= new String[]{ip};
				if(ip.indexOf(".")!=-1) b=ip.split("\\.");
				len=b.length*8;
				
				for(int i=0;i<b.length;i++)  Ip[i]=Integer.parseInt(b[i]);
				for(int i=b.length;i<4;i++)  Ip[i]=0;
			}
			IPpref ipPref=new IPpref(Ip,len);
			int m=0;
			int n1=a.size()-1;
			while(true){
				
				if(m>n1) {
					a.add(m, ipPref);
					break;
				}
				if(m==n1) {
					switch(compare(a.get(m).ip,Ip)) {
					case -1:
						a.add(m+1,ipPref);
						break;
					case 0:
						if(a.get(m).len>len) a.set(m, ipPref);
						break;
					case 1:
						a.add(m, ipPref);
						break;
					}
					break;
				}
				
				int k=(m+n1)/2;
				boolean isEq=false;
				switch(compare(a.get(k).ip,Ip)) {
				case -1:
					m=k+1;
					break;
				case 0:
					if(a.get(k).len>len) {
						a.set(k, ipPref);
					}
					isEq=true;
					break;
				case 1:
					n1=k-1;
					break;
				}
				if(isEq) break;
			}
		}
		
		int size=a.size()-1;
		int min;
		int[] f,L;
		for(int k=0;k<size;) {
			min=Math.min(a.get(k).len, a.get(k+1).len);
			f=and(a.get(k).ip,min);
			L=and(a.get(k+1).ip,min);
			if(compare(f,L)==0) {
				a.set(k, new IPpref(f,min));
				a.remove(k+1);
				size--;
				continue;
			}
			k++;
		}
		
		for(int k=0;k<size;) {
			if(a.get(k).len!=a.get(k+1).len) {
				k++;
				continue;
			}
			min=a.get(k).len-1;
			f=and(a.get(k).ip,min);
			L=and(a.get(k+1).ip,min);
			if(compare(f,L)==0) {
				a.set(k, new IPpref(f,min));
				a.remove(k+1);
				size--;
				if(k!=0) k--;
				continue;
			}
			k++;
		}
		
		reader.close();
		for(IPpref ip:a) {
			System.out.println(ip.ip[0]+"."+ip.ip[1]+
					"."+ip.ip[2]+"."+ip.ip[3]+"/"+ip.len);
		}

	}
	
	public static int compare(int[] m,int[] p) {
		for(int i=0;i<4;i++) {
			if(m[i]>p[i]) return 1;
			else if(m[i]==p[i]) {
				if(i==3) return 0;
				continue;
			}
			else break;
		}
		return -1;
	}
	
	public static int[] and(int[] p, int len) {
		int n=len/8;
		int m=len%8;
		int[] P=new int[4];
		for(int i=0;i<n;i++) P[i]=p[i];
		if(n<4) P[n]=p[n]&(-1<<(8-m));
		for(int i=n+1;i<4;i++) {
			P[i]=0;
		}
		return P;
	}
}

若转载请指明出处

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值