Uva 1590 IP Networks
阿新 • • 發佈:2019-02-03
題目:略(不會把PDF格式的題目直接轉過來,希望有大神可以指教一下)
心得:
1、讀題用了很久又到網上搜索了子網掩碼的百科才搞懂題目,唯一的思路是隻要找出給出的網路地址中二進位制位第一位不同的即可,難點是在實現的過程
2、我是把十進位制 -> 二進位制 -> 通過笨方法輸出;網上看到的一種簡潔的方法是用無符號整形儲存每個32位,這樣在二進位制 -> 輸出時程式碼會精簡很多。(感悟:對二進位制、2147483647、4294967295這樣的東西要極度敏感,這種東西大部分時候都可以用無符號整形來儲存)
3、第一次嚐到指標帶來的甜味,以後要儘量用指標來寫函式,多練習
程式碼:
PS:這題是到目前為止這次集訓收穫最大的一題,小有成就感!#include"stdio.h" #include"string.h" struct net{ int a,b,c,d; int ca[33]; }m[1001]; void zhuan(int a,int * p){ int j=7; while(a) { *(p+j)=a%2; a/=2; j--; } }//第一次嘗試用含指標的函式,指標很神奇,很好用 void stop(int i){ for(int j=i;j<32;j++) m[0].ca[j]=0; int q=0,w=0,e=0,r=0,z[4]; q=m[0].ca[7]+m[0].ca[6]*2+m[0].ca[5]*4+m[0].ca[4]*8+m[0].ca[3]*16+m[0].ca[2]*32+m[0].ca[1]*64+m[0].ca[0]*128; w=m[0].ca[7+8]+m[0].ca[6+8]*2+m[0].ca[5+8]*4+m[0].ca[4+8]*8+m[0].ca[3+8]*16+m[0].ca[2+8]*32+m[0].ca[1+8]*64+m[0].ca[0+8]*128; e=m[0].ca[7+16]+m[0].ca[6+16]*2+m[0].ca[5+16]*4+m[0].ca[4+16]*8+m[0].ca[3+16]*16+m[0].ca[2+16]*32+m[0].ca[1+16]*64+m[0].ca[0+16]*128; r=m[0].ca[7+24]+m[0].ca[6+24]*2+m[0].ca[5+24]*4+m[0].ca[4+24]*8+m[0].ca[3+24]*16+m[0].ca[2+24]*32+m[0].ca[1+24]*64+m[0].ca[0+24]*128; //這裡其實可以用函式代替,不過資料比較少的我還是喜歡用傻方法 if(i%8==7) z[i/8]=254; if(i%8==6) z[i/8]=252; if(i%8==5) z[i/8]=248; if(i%8==4) z[i/8]=240; if(i%8==3) z[i/8]=224; if(i%8==2) z[i/8]=192; if(i%8==1) z[i/8]=128; if(i%8==0) z[i/8]=0; //判斷i在8位中的位置,然後賦值,暫時想不到更好的解決辦法 for(int j=0;j<i/8;j++) z[j]=255; for(int j=i/8+1;j<=3;j++) z[j]=0; printf("%d.%d.%d.%d\n",q,w,e,r); printf("%d.%d.%d.%d\n",z[0],z[1],z[2],z[3]); } int main() { int n,i,j,f=0; while(scanf("%d",&n)!=EOF){f=0; memset(m,0,sizeof(m[0])*1001); for(i=0;i<n;i++){ scanf("%d.%d.%d.%d",&m[i].a,&m[i].b,&m[i].c,&m[i].d); zhuan(m[i].a,&m[i].ca[0]);zhuan(m[i].b,&m[i].ca[8]);zhuan(m[i].c,&m[i].ca[16]);zhuan(m[i].d,&m[i].ca[24]); } for(i=0;i<32&&f!=1;i++) //WA很多次就是因為這裡沒有加f!=1,最後一位如果出現不同會輸出兩次結果! { for(j=1;j<n&&f!=1;j++) { if(m[j].ca[i]!=m[j-1].ca[i]) {stop(i);f=1;} } } if(i==32&&f!=1) {printf("%d.%d.%d.%d\n",m[0].a,m[0].b,m[0].c,m[0].d);printf("255.255.255.255\n");} } }