CF1070

发布时间 2023-12-25 10:31:18作者: Call_me_Eric

CF1070

注:这次CF是和 @Terdy 合作进行的,在此处挂上Ta的博客链接 portal

CF1070B

link

CF1070B题意

联邦通信、信息技术和大众传媒监督局(Berkomnadzor)是伯利兹联邦执行机构,负责保护伯利兹普通居民免受现代互联网的威胁。

Berkomnadzor 拥有一份禁止使用的 IPv4 子网名单(黑名单)和一份允许使用的 IPv4 子网名单(白名单)。柏克兰的所有互联网服务提供商(ISP)都必须配置网络设备,阻止访问符合黑名单的所有 IPv4 地址。同时,ISP 必须允许(即不阻止)所有符合白名单的 IPv4 地址访问。如果某个 IPv4 地址与上述两个列表都不匹配,则由 ISP 决定是否阻止该地址。当且仅当一个 IPv4 地址与黑名单(白名单)中的某个子网相匹配时,它才会与黑名单(白名单)相匹配。一个 IPv4 地址可以同时属于白名单和黑名单,这种情况会导致矛盾(见输出描述中的无解情况)。

IPv4 地址是一个 32 位无符号整数,书写形式为 \(a.b.c.d\),其中每个值 $a,b,c,d $ 称为一个八位位组,是一个从 $0 $ 到 $255 $ 的十进制整数。例如,IPv4 地址 $ 192.168.0.1 $ 可以用以下表达式转换为 32 位数字 $ 192 \cdot 2^{24} + 168 \cdot 2^{16} + 0 \cdot 2^8 + 1 \cdot 2^0 $ 。第一个八位位组 $ a $ 编码最有意义(最左边的 $ 8 $ 位),八位位组 $ b $ 和 $ c $ 下面的 $ 8 $ 位块次有意义(按此顺序),八位位组 $ d $ 编码最无意义(最右边的 $ 8 $ 位)。

伯兰的 IPv4 网络与世界其他地方略有不同。伯兰没有保留地址或内部地址,而是使用所有可能的 $ 2^{32} $ 值。

一个 IPv4 子网用 $ a.b.c.d $ 或 $ a.b.c.d/x $ 表示(其中 $ 0 \le x \le 32 $ )。子网 $ a.b.c.d $ 包含一个地址 $ a.b.c.d $ 。一个子网 $ a.b.c.d/x $ 包含所有最左边(最重要)位 $ x $ 等于地址 $ a.b.c.d $ 最左边位 $ x $ 的 IPv4 地址,要求子网 $ a.b.c.d/x $ 最右边(最不重要)位 $ 32 - x $ 为 0。

与子网 $ a.b.c.d/x $ 匹配的所有地址自然会形成一个连续的范围。该范围从地址 $ a.b.c.d $ 开始(其最右边的 $ 32 - x $ 位为零)。该范围以地址 $ a.b.c.d $ 的最左端 $ x $ 位等于地址 $ a.b.c.d $ 的最左端 $ x $ 位,且其最右端 $ 32 - x $ 位全为 1 的地址结束。子网恰好包含 $ 2^{32-x} $ 地址。子网 $ a.b.c.d/32 $ 恰好包含一个地址,也可以只用 $ a.b.c.d $ 表示。

例如,子网 $ 192.168.0.0/24 $ 包含 256 个地址。$ 192.168.0.0 $ 是地址范围的第一个地址,$ 192.168.0.255 $ 是最后一个地址。

Berkomnadzor 的工程师制定了一项提高 Berland 全球网络性能的计划。他们不想同时维护白名单和黑名单,而只想建立一个包含最少子网数量的优化黑名单。这样做的目的是阻止所有符合优化黑名单的 IPv4 地址,并允许所有其他地址访问。当然,旧黑名单中的 IPv4 地址必须继续封锁,而旧白名单中的所有 IPv4 地址必须继续允许。那些既不符合旧黑名单也不符合旧白名单的 IPv4 地址,无论其以前是否可以访问,都可以被阻止或允许。

请编写一个程序,将黑名单和白名单作为输入,并生成优化黑名单。优化后的黑名单必须包含尽可能少的子网,并满足上述所有 IPv4 地址可访问性要求。

源列表中的 IPv4 子网可以任意交叉。如果某个 IPv4 地址同时符合源白名单和黑名单,请输出一个数字-1。

CF1070B题解

CF1070B代码

CF1070D

link

CF1070D题意

Vasya已经很多次忘记将垃圾从公寓里扔出去。现在他想制定一个计划并遵守它。
对于接下来的n天Vasya知道他每天会制造ai的垃圾。Vasya会将垃圾放在垃圾袋中并扔掉垃圾袋每个袋子能装k的垃圾,一天可以扔掉或使用多个垃圾袋。
Vasya想要使用最少的垃圾袋,你需要输出最少的垃圾袋数量。

当天生产的垃圾是可以留到第二天的,但最多留到第二天。

CF1070D题解

发现每次先用前一天的垃圾构成垃圾袋,然后在装今天的,有剩余的扔给明天。
特判下边界即可。

CF1070D代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
    int x = 0, f = 1;char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}
    return x * f;
}
int n, k;
signed main(){
    n = read();k = read();int lst = 0, ans = 0;
    for(int i = 1;i <= n;i++){
        int x = read();
        if(x + lst <= k && lst != 0){ans++;lst = 0;continue;}
        else{
            if(lst){x -= (k - lst);ans++;}
            ans += x / k;lst = x % k;
        }
    }
    if(lst)ans++;
    printf("%lld\n",ans);
    return 0;
}