2017 计蒜之道 初赛 第五场

 A. UCloud 机房的网络搭建
UCloud 刚刚建立一个新机房,近日正在进行网络搭建。机房内有 nn 台服务器和 mm 个分线器,整个机房只有一个网线出口。分线器的作用是将一根网线转换成多根网线。蒜头君也知道每个分线器输出的最大网线根数(不一定要将分线器输出的每根线都用上),问你至少需要使用多少个分线器才能使得每台服务器都有网线可用。

输入格式
第一行输入 n,m(0 \le n,m \le 100)n,m(0≤n,m≤100)。

第二行输入包含 mm 个整数的数组 A(0 \le A_i \le 10)A(0A 
i
​    ≤10) 表示每个分线器输出的最大网线根数。

输出格式
输出最少需要的分线器数量。若不能使得所有服务器都有网线可用,输出一行Impossible。


解析: 这题得按照图片所给写程序,按照自己的思路设计是不对的,要考虑边界值
#include<bits/stdc++.h>
using namespace std;
const int maxn = 110;
int a[maxn];
int n,m;
bool cmp(int x,int y)
{
    return x > y;
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin >> n >> m;
    for(int i = 0; i < m; i ++)
        cin >> a[i];
    sort(a,a+n,cmp);
    int sum = 1;
    if(n<=1)
    {
        cout << 0 << endl;
        return 0;
    }
    n-=a[0];
    for(int i = 1; i < m; i ++)
    {


        if(n <= 0) break;
        else
        {
            n = n -  (a[i] - 1);
            ++ sum;
        }


    }
    if(n>0)
        cout << "Impossible"<< endl;
    else
        cout << sum << endl;
    return 0;
}
 B. UCloud 的安全秘钥(简单)
 每个 UCloud 用户会构造一个由数字序列组成的秘钥,用于对服务器进行各种操作。作为一家安全可信的云计算平台,秘钥的安全性至关重要。因此,UCloud 每年会对用户的秘钥进行安全性评估,具体的评估方法如下:

首先,定义两个由数字序列组成的秘钥 aa 和 bb 近似匹配(\approx≈) 的关系。aa 和 bb 近似匹配当且仅当同时满足以下两个条件:

|a|=|b|∣a∣=∣b∣,即 aa 串和 bb 串长度相等。
对于每种数字 cc,cc 在 aa 中出现的次数等于 cc 在 bb 中出现的次数。
此时,我们就称 aa 和 bb 近似匹配,即 a \approx ba≈b。例如,(1,3,1,1,2)\approx(2,1,3,1,1)(1,3,1,1,2)≈(2,1,3,1,1)。

UCloud 每年会收集若干不安全秘钥,这些秘钥组成了不安全秘钥集合 TT。对于一个秘钥 ss 和集合 TT 中的秘钥 tt 来说,它们的相似值定义为:ss 的所有连续子串中与 tt 近似匹配的个数。相似值越高,说明秘钥 ss 越不安全。对于不安全秘钥集合 TT 中的每个秘钥 tt,你需要输出它和秘钥 ss 的相似值,用来对用户秘钥的安全性进行分析。

输入格式
第一行包含一个正整数 nn,表示 ss 串的长度。

第二行包含 nn 个正整数 s_1,s_2,...,s_n(1\leq s_i\leq n)s 
1
​    ,s 
2
​    ,...,s 
n
​    (1≤s 
i
​    ≤n),表示 ss 串。

接下来一行包含一个正整数 mm,表示询问的个数。

接下来 mm 个部分:

每个部分第一行包含一个正整数 k(1\leq k\leq n)k(1≤k≤n),表示每个 tt 串的长度。

每个部分第二行包含 kk 个正整数 t_1,t_2,...,t_k(1\leq t_i\leq n)t 
1
​    ,t 
2
​    ,...,t 
k
​    (1≤t 
i
​    ≤n),表示 TT 中的一个串 tt。

输入数据保证 TT 中所有串长度之和不超过 200000200000。

对于简单版本:1\leq n,m\leq 1001≤n,m≤100;

对于中等版本:1\leq n\leq 50000,1\leq m\leq 5001≤n≤50000,1≤m≤500;

对于困难版本:1 \le n \le 50000, 1 \le m \le 1000001≤n≤50000,1≤m≤100000。

输出格式
输出 mm 行,每行一个整数,即与 TT 中每个串 tt 近似匹配的 ss 的子串数量。

样例解释
对于第一个询问,(3,2,1,3)\approx(2,3,1,3)(3,2,1,3)≈(2,3,1,3),(3,2,1,3)\approx(3,1,3,2)(3,2,1,3)≈(3,1,3,2);

对于第二个询问,(1,3)\approx(3,1)(1,3)≈(3,1),(1,3)\approx(1,3)(1,3)≈(1,3);

对于第三个询问,(3,2)\approx(2,3)(3,2)≈(2,3),(3,2)\approx(3,2)(3,2)≈(3,2)。

样例输入
5
2 3 1 3 2
3
4
3 2 1 3
2
1 3
2
3 2
样例输出
2
2
2

解析按照题目所给模拟。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
int a[150],b[150];
int mp[150],mp1[150];
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;
    cin >> n;
    for(int i = 0;i < n;i ++)
    {
        cin >> a[i];
    }
    int m;
    cin >> m;
    while(m --)
    {
        int k;
        memset(mp,0,sizeof(mp1));
        cin >> k;
        int cnt = 0;
        for(int i = 0;i < k;i ++)
        {
            cin >> b[i];
            mp[b[i]] ++;///把现有数组标记
        }
        int start = n - k; // start position
        for(int i = 0;i <= start;i ++)
        {
            bool flag = true;
             memset(mp1,0,sizeof(mp1));
            for(int j = i;j < k + i;j ++)
            {
                mp1[a[j]] ++;/// 把原数组的标记
            }
            for(int i = 0;i < k;i ++)
            {
                if(mp[b[i]] != mp1[b[i]])
                {
                    flag = false;
                    break;
                }
            }
            if(flag) cnt ++;
        }
        cout << cnt << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值