我的做题日志(1),来源:COCI2017,SDOJ

Mirko在一家大型IT公司暑假实习。 该公司构建了一个由N行和M列组成的大型数据库。

在他第一天,Mirko收到了Q个查询。 每个查询由M个数字组成。

然而,一些数字在传输过程中丢失,所以它们用-1表示。 Mirko想知道数据库中有多少行对应于查询,即数据库的行数与查询相同,不包括-1。

例如,如果查询是-1 3 2的形式,那么我们需要统计满足,第一列是任何数字,第二列中的数字为3 ,第3列中的数字2。

由于他刚开始实习,Mirko需要你的帮助。 帮助他并回答查询!

输入

第一行输入包含数据库的大小N(1≤N≤1e3)和M(1≤M≤1e3)。

以下N行中的每一行包含M数字A ij(1≤Aij≤10^6),数据库的内容。

以下行包含Q(1≤Q≤50),查询次数。

以下Q行中的每一行包含M个数字Bij(Bij = -1 或1≤Bij≤10^6),表示第i个查询的描述。

输出

输出必须包含Q行,每行包含X,表示第i个查询的答案。


样例略


题解:

初次写题解,不喜勿喷。本题就是一道带有一定思维难度的模拟,因为数据较小,所以普及提高还可以出,(Q<=1000时,用分块FFT搞定,这个至少 省选(也可能是国赛才有,毕竟还没考过))。直接按照题意写会TLE,所以需要注意一些细节。

首先是在每个查询的位置,这是本题主要卡时间的地方,至少我在SDOJ上被卡掉了20分(类乐多赛制),我们在这里只需要一个二层循环实现,但很容易写出一个来标记,一个来查找这种思维简单但十分费事的算法。所以应该按照题目给出的每组数据,从前到后扫描,匹配每个位置,遇到-1就continue,同时用一个变量来记录方案数,我用的是ans。这个ans有个很巧妙的设计,就是在开始时,将ans初始化为N,就是行数(因为是查询是询问有多少行),然后一旦失配,就break,并将ans--。


题解说完了,上代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,m,a[N][N],b[N];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);
	int Q;scanf("%d",&Q);
	while(Q--){
		for(int i=1;i<=m;i++)scanf("%d",&b[i]);
		int ans=n;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(b[j]==-1)continue;
				else{
					if(a[i][j]==b[j])continue;
					else{ans--;break;}
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0; 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值