手串(暴力) - 今日头条2018校园招聘后端方向(9.10)

这是一道来自2018年今日头条校园招聘后端笔试的题目,要求判断一条环形手串中是否存在某种颜色在任意连续的m个串珠中出现超过一次。输入包括串珠数量n,连续珠子限制m,以及颜色种类c。通过遍历并检查每个珠子的颜色出现情况,来确定不符合要求的颜色数量。解题策略是遍历每个珠子并检查其后的m个珠子,遇到重复颜色则计数,并在达到颜色上限时提前结束遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间限制:1秒
空间限制:65536K

题目描述
作为一个手串艺人,有金主向你订购了一条包含n个杂色串珠的手串——每个串珠要么无色,要么涂了若干种颜色。为了使手串的色彩看起来不那么单调,金主要求,手串上的任意一种颜色(不能包含无色),在任意连续的m个串珠中至多出现一次(注意这里手串是一个环形)。手串上的颜色一共有c种。现在按顺时针序告诉你n个串珠的手串上,每个串珠用所包含的颜色分别有哪些。请你判断该手串上有多少种颜色不符合要求。即询问有多少种颜色在任意连续m个串珠中出现了至少两次。

输入描述:
第一行输入n, m, c三个数,用空格隔开。(1<=n<=10000, 1<=m<=1000, 1<=c<=50)接下来n行每行的第一个整数num_i(0<=num_i<=c)表示第i颗珠子有多少种颜色。接下来依次读入num_i个数字,每个数字x表示第i颗珠子上包含第x种颜色(1<=x<=c)

输出描述:
一个非负整数,表示该手链上有多少种颜色不符需求。

示例1
输入
5 2 2
3 1 2 3
0
2 2 3
1 2
1 3

输出
2

说明
第一种颜色出现在第1颗串珠,与规则无冲突。
第二种颜色分别出现在第1,3,4颗串珠,第3与第4颗串珠相邻,所以不合要求。
第三种颜色分别出现在第1,3,5颗串珠,第5颗串珠的下一个是第1颗,所以不合要求。
总计有2中颜色的分布是有问题的。
这里第2颗串珠是透明的。

解题思路:由于数据并非很大,10000*1000可以在接受范围内,所有对于每没一个串珠都往后遍历m个判断是否有相同的颜色,并把相同颜色做标记之后遇到相同颜色直接continue,还有个优化情况就是当不符合的颜色达到c的时候就可以直接停止了。注意的问题是遍历到最后的时候要往返到第一个重新遍历直到数量达到m个,还有其它一些m>=n之类的边界条件。
这里不用两边都访问,因为全部都访问一边就可以保证所有的情况都在内了。

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;

bool color[55];
vector<int> V[10005];

int main()
{
    int n, m, c, num, x;
    while(cin >> n >> m >> c)
    {
        memset(color, 0, sizeof(color));
        for(int i = 0; i < n; ++i)
            V[i].clear();
        for(int i = 0; i < n; ++i)
        {
            cin >> num;
            while(num--)
            {
                cin >> x;
                V[i].push_back(x);
            }
        }
        if(m==1)
        {
            cout << 0 << endl;
            continue;
        }
        if(m>=n)
        {
            cout << c << endl;
            continue;
        }

        int ans = 0;
        for(int i = 0; i < n; ++i)
        {
            if(ans==c)
                break;
            for(int j = 0; j < V[i].size(); ++j)
            {
                if(color[V[i][j]])
                    continue;
                int tmp = 1;
                int k = i+1;
                while(tmp<m)
                {
                    if(k==n)
                        k = 0;
                    for(int l = 0; l < V[k].size(); ++l)
                        if(V[k][l]==V[i][j] && !color[V[i][j]])
                        {
                            color[V[i][j]] = true;
                            ans++;
                        }
                    k++;
                    tmp++;
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}
/*
5 2 2
3 1 2 3
0
2 2 3
1 2
1 3
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值