竞赛之路-智算之道-初赛第一场-排队

题目如下:
排队
理解题意:n个人m个窗口,最多100个窗口,剔除掉所有数字为窗口数字ai倍数的人。
1.输入n、m,循环输入每个窗口中的数字,用数组a存放。
2.从1开始循环判断每一个人
3.嵌套循环对是否需要带出队伍进行判断
4.输出剩下的人数

注:该方法暴力枚举,时间复杂度为O(n*m)

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;//n个人,m个窗口
	int a[100];//最大100个ai
	cin >> n >> m;
	for (int i = 0; i < m; i++)//输入数据
		cin >> a[i];
	int number = 0;//需要带出队伍的人数
	for (int i = 1; i <= n; i++)//对每一个数循环判断
	{
		int flag = 0;//标志变量,为1则带出队伍
		for (int j = 0; j < m; j++)//对是否为每个窗口进行判断
			if (i % a[j] == 0)//如果是ai倍数则标志变量置1
				flag = 1;
		if (flag)//如果标志变量为1则带出队伍的人数加一
			number++;
	}
	cout << n - number;//输出队伍中还剩下的人数
	return 0;
}
//排队问题,暴力枚举,时间复杂度O(n*m)

但是最长耗时居然达到了27ms,这让我觉得很不可思议,于是我找到了大佬的0ms代码

如下:

#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

int a[105];
bool out[100005];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++)
    {
        scanf("%d", &a[i]);
    }
    int ans = n;
    for (int i = 0; i < m; i++)
    {
        for (int j = 1; a[i] * j <= n; j++)
        {
            if (!out[a[i] * j])
            {
                out[a[i] * j] = true;
                ans--;
            }
        }
    }
    printf("%d", ans);
    return 0;
}

原代码出处点这儿

cin、scanf和头文件对耗时的影响很小,我发现关键还是出在我的算法上。
大佬的思路是:
1.先用bool存好n个false
2.对于每一个窗口的数,用j表示倍数,循环结束条件为a[i] * j <= n,然后要剔除的位置赋值为true,总数减一

注:bool类型为全局变量时默认为false

题外话:对于数据不太大的情况我们用最大数的数组,测试未通过才用new分配内存空间。(我发现在本题中用new的时间比数组更长,达到了33ms)

最终代码:

#include <bits/stdc++.h>
using namespace std;
bool que[100000];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n, m;//n个人,m个窗口
	int a[100];//最大100个ai
	cin >> n >> m;
	for (int i = 0; i < m; i++)//输入数据
		cin >> a[i];
	int num = n;//队伍中的人数
	for (int i = 0; i < m; i++)//对每一个窗口数的倍数进行剔除
		for (int j = 1; a[i] * j <= n; j++)//j为倍数,找到n中所有的当前窗口数的倍数
			if (!que[a[i] * j])//只要que数组当前位置的值为false
			{
				que[a[i] * j] = true;//给当前却que数组的位置赋值true,用以判断,避免重复计算
				num--;//剔除当前位置的人
			}
	cout << num;//输出队伍中还剩下的人数
	return 0;
}

时间优化到了最多耗时1ms,达到了我理想的效果。

扫描二维码关注公众号,回复: 11430384 查看本文章

猜你喜欢

转载自blog.csdn.net/DGany/article/details/107549825