1. 程式人生 > >今日頭條2018校園招聘後端方向(9.10)

今日頭條2018校園招聘後端方向(9.10)

時間限制: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 */