1 条题解

  • 2
    @ 2021-8-17 13:18:30

    仔细读完题之后,我们可以想到枚举每一天,然后从这一天开始往后k天,看一看这k天内有几天是没有打卡的,然后去找一个最小值。

    代码如下:

    此代码能得到60分,要注意双重for循环的范围,以及最小值变量的初始化,这里我直接初始化成了int的最大值,定义成INT_MAX即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,m,k,x,num,ans=INT_MAX,a[100010];
    
    int main()
    {
    	cin >> m >> k >> n;
    	for(int i=1;i<=n;i++)
    	{
    		cin >> x;
    		a[x] = 1;
    	}
    	for(int i=1;i<=m-k+1;i++)
    	{
    		num = 0;
    		for(int j=i;j<=i+k-1;j++)
    		{
    			num += a[j];
    		}
    		ans = min(ans,num);
    	}
    	cout << ans;
    	return 0;
    }
    

    如果想要得到100分,我们得使用前缀和来优化,避免超时,前缀和可以快速求区间和,相对双重循环来说减少了一重循环,也就从O(n2)O(n^2)时间复杂度降到了O(n)O(n),具体代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100005;
    
    int sum[N],a[N];
    int m,k,n,x,ans=N;
    
    int main()
    {
    	cin >> m >> k >> n;
    	for(int i=1;i<=n;i++)
    	{
    		cin >> x;
    		a[x] = 1;
    	}
    	for(int i=1;i<=m;i++)
    	{
    		sum[i] = sum[i-1]+a[i];
    	}
    	for(int i=1;i<=m-k+1;i++)
    	{
    		ans = min(ans,sum[i+k-1]-sum[i-1]);
    	}
    	cout << ans;
    	return 0;
    }
    

    如果前缀和的知识忘记了,快去L7-1再复习一下哦~

    • 1

    信息

    ID
    1211
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    301
    已通过
    105
    上传者