第九次模拟测试-1

题目描述 这一天,TT因为疫情在家憋得难受,在云吸猫一小时后,TT决定去附近自家的山头游玩。
TT来到一个小湖边,看到了许多在湖边嬉戏的鸭子,TT顿生羡慕。此时他发现每一只鸭子都不 一样,或羽毛不同,或性格不同。TT在脑子里开了一个map<鸭子,整数> tong,把鸭子变成了 一些数字。现在他好奇,有多少只鸭子映射成的数的数位中不同的数字个数小于k。 输入描述 输入第一行包含两个数n,k,表示鸭子的个数和题目要求的k。
接下来一行有n个数, a i a_i ai,每个数表示鸭子被TT映射之后的值。 输出描述 输出一行,一个数,表示满足题目描述的鸭子的个数。
无行末空格 样例输入
6 5 123456789 9876543210 233 666 1 114514
样例输出
4
数据组成 数据点 n k a i a_i ai 1 n<=1000 k=10 1 0 6 10^6 106 2 n<=1000 k=1 1 0 6 10^6 106 3,4,5 n<= 1 0 5 10^5 105 k<=100 1 0 9 10^9 109 6,7,8,9,10 n<= 1 0 6 10^6 106 k<= 1 0 6 10^6 106 1 0 15 10^{15} 1015
题目分析:
本题有一个虚晃一枪,就是不同的数字一定是小于等于10个的,所以K大于10那就意味着所有可能出现的数都是符合要求的。但是我们发现输入的数范围太大了,而我们想要的是数位而不是整数,所以我们用字符表示。

char a[20];

然后我们为了统计不重复出现的字符数,我们可以用一个布尔数组来储存,只要出现了就置为true,如果是true就不算了,否则就不同的数字++,之后比较k就可以了。

	for(int i=1;i<=n;i++)
	{
		scanf("%s",&a);
		for(int j=0;a[j]!='\0';j++)
		{
			if(b[a[j]-48]==false)
			{
				b[a[j]-48]=true;
				count++;
			}
		}
		if(count<k)
		{
			num++;
		}		

在这里我们发现一个问题,就是在自建的OJ上没问题,但是在VJ上就会TLE,助教解释如下:
关于T1有些同学超时的问题:(我猜你用了STL
正解的复杂度是 151e6,用了stl的话会变成 151e6*log10
你可能认为这个时间复杂度并没有超过 1e8所以不会T
但是你要考虑到 你的程序是有带着一个常数的 而计算复杂度的时候是没有常数的 这个常数是超时的原因
以后做题的时候如果估算时间复杂度发现在1e7左右的时候需要观察题目给出的时限,如果是1s的话就需要注意常数问题
而且评测机的性能是有波动的,有的快有的慢,所以当时间复杂度逼近1e8的时候一定要谨慎。
好的,于是我就照做了,本来我想着是memset的问题,于是我就用手动清零了。

		for(int m=0;m<10;m++)
		{
			b[m]=false;
		}

但是当我尝试了1145141919810893364次依然发现在test5上TLE,后来我再品味这句话,加上之前助教给的经验,我突然想到,哦,会不会是要把cin改成scanf?果然啊!以往的时候都直接说了,看来这次也是这个样子!不过改的时候发现问题了,我一开始用的是string啊!好像scanf不能直接用这个,那咋办嘛?!于是改成了char,发现用单个字符是不能直接编译的,于是设了个字符数组,这样就能用scanf输入,之后AC了!!!!!!!看来学长为了让我们用scanf和printf花了不少心思啊(虽然他说一开始没想到卡这个)!
代码如下:

#include<iostream>
using namespace std;
char a[20];
bool b[100];
int main()
{
	int n,k;
	cin>>n>>k;
	int count=0;
	int num=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",&a);
		for(int m=0;m<10;m++)
		{
			b[m]=false;
		}	
		for(int j=0;a[j]!='\0';j++)
		{
			if(b[a[j]-48]==false)
			{
				b[a[j]-48]=true;
				count++;
			}
		}
		if(count<k)
		{
			num++;
		}
		count=0;
	}
	cout<<num;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值