要点

  • scanf输入uint8_t, 使用宏 "%" SCNu8
  • 自定义结构体,方便阅读
  • 判断IP失效 (ms + (ms & (-ms))) || !(ms + 1) (ms表示掩码)
  • 基本的IP类型判断
#include <bits/stdc++.h>
using namespace std;
typedef struct {
    union {
        struct {
            uint8_t p4;
            uint8_t p3;
            uint8_t p2;
            uint8_t p1;
        } dip;
        struct {
            uint8_t m4;
            uint8_t m3;
            uint8_t m2;
            uint8_t m1;
        } dmk;
        uint32_t ip;
        uint32_t mk;
    } addr;
} IP, MASK;
int a, b, c, d, e, err, pri;
int main() {
    IP ip; MASK mk;
    int num = 0;
    while (~(num = scanf("%" SCNu8 ".%" SCNu8 ".%" SCNu8 ".%" SCNu8 "~%" SCNu8 ".%" SCNu8 ".%" SCNu8 ".%" SCNu8 "\n", 
         &ip.addr.dip.p1, &ip.addr.dip.p2, &ip.addr.dip.p3, &ip.addr.dip.p4, 
         &mk.addr.dmk.m1, &mk.addr.dmk.m2, &mk.addr.dmk.m3, &mk.addr.dmk.m4))) {
        int ms = mk.addr.mk;
        if (num < 8 || (ms + (ms & (-ms))) || ms + 1 == 0) {
            err++;
            continue;
        }
        uint8_t p1 = ip.addr.dip.p1;
        uint8_t p2 = ip.addr.dip.p2;
        if (p1 == 10 || (p1 == 172 && p2 >= 16 && p2 < 32) || (p1 == 192 && p2 == 168)) pri++;
        if (p1 >= 1 && p1 < 127) a++;
        else if (p1 >= 128 && p1 < 192) b++;
        else if (p1 >= 192 && p1 < 224) c++;
        else if (p1 >= 224 && p1 < 240) d++;
        else if (p1 >= 240 && p1 < 256) e++;
    }
    printf("%d %d %d %d %d %d %d\n", a, b, c, d, e, err, pri);
    return 0;
}