1. 程式人生 > >算法74----手串(莫隊算法)

算法74----手串(莫隊算法)

size play ack adb 題目 cstring esp %d can

一、題目:

作為一個手串藝人,有金主向你訂購了一條包含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 3
3 1 2 3
0
2 2 3
1 2
1 3

輸出例子1:
2

例子說明1:
第一種顏色出現在第1顆串珠,與規則無沖突。
第二種顏色分別出現在第 1,3,4顆串珠,第3顆與第4顆串珠相鄰,所以不合要求。
第三種顏色分別出現在第1,3,5顆串珠,第5顆串珠的下一個是第1顆,所以不合要求。
總計有2種顏色的分布是有問題的。 
這裏第2顆串珠是透明的。

二、C++代碼:

https://www.nowcoder.com/discuss/39688?type=0&order=0&pos=24&page=1

http://s3.nowcoder.com/discuss/39735?type=6&order=0&pos=10859&page=1

莫隊算法:

https://www.cnblogs.com/Paul-Guderian/p/6933799.html

https://www.cnblogs.com/CsOH/p/5904430.html

技術分享圖片
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <vector>
using
namespace std; typedef long long LL; int cnt[55], n, m, c; vector<int> cs[20005]; set<int> ans; void check() { for (int i = 1; i <= c; i ++) { if(cnt[i] > 1) ans.insert(i); } } int main() { int p, x; scanf("%d %d %d", &n, &m, &c); for (int i = 1; i <= n; i ++) { scanf("%d", &p); while(p --) { scanf("%d", &x); cs[i].push_back(x); } cs[i + n] = cs[i]; } for (int i = 1; i <= n + m; i ++) { int sz = cs[i].size(); for (int j = 0; j < sz; j ++) { cnt[cs[i][j]] ++; } if(i > m) { sz = cs[i - m].size(); for (int j = 0; j < sz; j ++) { cnt[cs[i - m][j]] --; } } check(); } cout << ans.size() << endl; return 0; }
View Code

算法74----手串(莫隊算法)