列表

详情


NC50345. Secret Message 秘密信息

描述

贝茜正在领导奶牛们逃跑。为了联络,奶牛们互相发送秘密信息。
信息是二进制的,共有M条。反间谍能力很强的约翰已经部分拦截了这些信息,知道了第i条二进制信息的前b_i位。他同时知道,奶牛使用N条密码。但是,他仅仅了解第j条密码的前c_j位。
对于每条密码j,他想知道有多少截得的信息能够和它匹配。也就是说,有多少信息和这条密码有着相同的前缀。当然,这个前缀长度必须等于密码和那条信息长度的较小者。

输入描述

第一行输入N和M,之后N行描述秘密信息,之后M行描述密码.每行先输入一个整数表示信息或密码的长度,之后输入这个信息或密码。
所有数字之间都用空格隔开。

输出描述

共M行,输出每条密码的匹配信息数。

示例1

输入:

4 5
3 0 1 0
1 1
3 1 0 0
3 1 1 0
1 0
1 1
2 0 1
5 0 1 0 0 1
2 1 1

输出:

1
3
1
1
2

说明:

4条信息,5条密码
截获的信息前缀是010,1,100,110,可能的密码前缀是0,1,01,01001,11。
0只配对010;
1配对1,100,110;
01只配对010;
01001配对010;
11配对1,110。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 168ms, 内存消耗: 2912K, 提交时间: 2019-12-09 18:55:59

#include<bits/stdc++.h>
using namespace std;


const int MAXN = 5e5 + 5;
struct Node {
  int val;
  int cnt;
  int ch[2];
};
int sz;
Node nodes[MAXN];

void insert(vector<int> A) {
  int cur = 0;
  for (auto a: A) {
    int &nxt = nodes[cur].ch[a];
    if (nxt == 0) nxt = ++sz;
    nodes[nxt].cnt++;
    cur = nxt;
  }
  nodes[cur].val++;
}

int query(vector<int> A) {
  int cur = 0;
  int cnt = 0;
  for (auto a: A) {
    int nxt = nodes[cur].ch[a];
    if (nxt == 0) return cnt;
    cur = nxt;
    cnt += nodes[cur].val;
  }
  // return cnt;
  return nodes[cur].cnt+cnt-nodes[cur].val;
}

int main() {
  ios::sync_with_stdio(false);
  int N, M; cin >> N >> M;
  while (N--) {
    int n; cin >> n;
    vector<int> A(n); for (auto &a: A) cin >> a;
    insert(A);
  }
  while (M--) {
    int n; cin >> n;
    vector<int> A(n); for (auto &a: A) cin >> a;
    cout << query(A) << endl;
  }
}

C++ 解法, 执行用时: 179ms, 内存消耗: 2552K, 提交时间: 2021-12-05 19:57:10

#include<bits/stdc++.h>
using namespace std;
bool s[10001];
int trie[1000001][2],f[1000001],sum[1000001],tot;
int search(int &len,bool s[]){
	int ans = 0,t = 0,i = 0;
	for (;i < len;i++){
		t = trie[t][s[i]];
		if (!t)break;
		if (i != len - 1)
			ans += f[t];
	}
	if (i == len)ans += sum[t];
	return ans;
}
int main(){
	int n,m,a,t,i,*p;
	cin>>n>>m;
	while (n--){
		cin>>a;
		for (i = 0;i < a;i++)
			cin>>s[i];
		t = 0;
		for (i = 0;i < a;i++){
			p = &trie[t][s[i]];
			if (!*p)*p = ++tot;
			t = *p;
			sum[t]++;
		}
		f[t]++;
	}
	while (m--){
		cin>>a;
		for (i = 0;i < a;i++)
			cin>>s[i];
		cout<<search(a,s)<<endl;
	}
	return 0;
}

上一题