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;
}
}
若转载请指明出处