做完之后,有看下网上大神的报告,都觉得没有什么坑,看来自己的英语有待提高,自己错误好几遍都是错在了EOF上
我看样例输入输出还是,还是原文都没有看到end of file,这是一个惨痛的教训!!!
整体思路呢,是将所有输入的IP转换成二进制存到二维数组里面,因为题目中说最多输入不超过1000个,所以直接char str[1005][40];
在搜索所有的IP地址,从头开始,找到第一个不一样的数字,记下位置(假设是cont)。然后开一个记录子网掩码的数组让前cont 个
元素都为1,后面的都为0,(这是子网掩码的定义,题目中有阐述),在让第一组IP地址(因为无论哪一组IP前cont个元素肯定都一样,不妨
直接找第一组IP),与子网掩码进行与(&)运算,这样前cont个元素不变,后面全为0,这恰好是最小IP!!
#include<stdio.h>
#include<string.h>
#define MAX 1005
#define N 40
char str[MAX][N];
void in_change(int n,char st[])
{
int a = n,i = 7;
char num[N];
num[8] = 0;
while(a != 0)
{
num[i] = a % 2 + 48;
a /= 2;
i--;
}
for(; i > -1; i--)
num[i] = '0';
strcat(st,num);
}
void print_netmask(int n,int Num[],int num2[])
{
int v = 0,i,j,flag = 0;
for(i = 0; i < 32; i++)
{
char ch = str[1][i];
for (j = 1; j <= n; j++)
{
if (str[j][i] != ch)
{
flag = 1;
break;
}
}
if (flag)break;
}
int cont = i;
char ans_mask[N],ans_adress[N];
for (i = 0; i < cont; i++)
ans_mask[i] = '1';
for (; i < 32; i++)
ans_mask[i] = '0';
ans_mask[i] = 0;
for (i = 0; i < 32; i++)
ans_adress[i] =( (ans_mask[i] - 48) & (str[1][i] - 48)) + 48;
ans_adress[i] = 0;
for (i = 0; i < 4; i++)
{
v = 0;
int v2 = 0;
for (j = i * 8; j < (i + 1 ) * 8; j++)
{
v = v * 2 + ans_mask[j] - 48;
v2 = v2 * 2 + ans_adress[j] - 48;
}
Num[i] = v;
num2[i] = v2;
}
}
int main()
{
int num1[N],num2[N],num[5],m;
while(~scanf("%d",&m))
{
int i,j,cont;
memset(str,0,sizeof(str));
for (cont = 1; cont <= m; cont++)
{
scanf("%d.%d.%d.%d",&num[1],&num[2],&num[3],&num[4]);
for (i = 1; i <= 4; i++)in_change(num[i],str[cont]);
}
print_netmask(m,num1,num2);
printf("%d.%d.%d.%d\n",num2[0],num2[1],num2[2],num2[3]);
printf("%d.%d.%d.%d\n",num1[0],num1[1],num1[2],num1[3]);
}
return 0;
}