【NOIP】XR-4模拟赛,Oler教练的上班策略

7 篇文章 0 订阅

author:&Carlton

tag:模拟

topic:【NOIP】XR-4模拟赛,Oler教练的上班策略

language:C++

website:洛谷

date:2023年8月19日


目录

题目

我的题解

思路

源代码

改进


题目

我的题解

思路

        ①将学生有空时间存储在一个n*m的二维数组中,n个学生,m套题。

        ②审核数组中每一个数字在多少个不同列中出现,即每一天需要准备多少套不同的题。

        ③将次数分别存储在一个一维数组中,最后输出数组的值即为结果。

源代码

#include <iostream>
using namespace std;
#define DEBUG 0


int main()
{
    int i, j, n, m, k, t, temp;
    cin >> n >> m >> k;
    //动态分配内存,自动初始化为0
    //用二维数组存储学生数据
    int* a = (int*)calloc(sizeof(int), m * n);
    //最后输出准备场数的数组
    int* b = (int*)calloc(sizeof(int), k);
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            cin >> *(a+i*m+j);
        }
    }
#if DEBUG
    cout << endl;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            cout << *(a + i * m + j)<< " ";
        }
        cout << endl;
    }
    cout << endl;
    for (j = 0; j < m; j++)
    {
        for (i = 0; i < n; i++)
        {
            cout << *(a + i * m + j) << " ";
        }
        cout << endl;
    }
#endif
    //每一个数字在多少个不同列中出现
    for (t = 1; t <= k; t++)
    {
        //第j列即第j套题,按列寻找
        for (j = 0; j < m; j++)
        {
            for (i = 0; i < n; i++)
            {
                if (*(a+i*m+j) == t)
                {
                    //当天要讲的套题数+1
                    b[t - 1]++;
                    //跳出当前列循环
                    break;
                }
                #if DEBUG
                {
                    cout << b[0] << endl;
                }
                #endif
            }
        }
    }
    //输出结果
#if !DEBUG
    for (i = 0; i < k; i++)
    {
        cout << b[i] << " ";
    }
#endif
    return 0;
}

        但计算个数时有三层for循环,是个O(n^{_{}3})时间复杂度的算法,超时了。

改进

        用一个二维数组标记,避免同套题重复记数

#include <iostream>
using namespace std;

int main()
{
    int i, j, n, m, k;
    cin >> n >> m >> k;
    //动态分配内存,自动初始化为0
    //用二维数组存储学生数据
    int* stu = (int*)calloc(sizeof(int), n * m);
    //最后输出准备场数的数组
    int* ans = (int*)calloc(sizeof(int), k);
    int* mark = (int*)calloc(sizeof(int), k * m);
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            cin >> *(stu + i * m + j);
        }
    }
    //第stu[i][j]天要做第j道题
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            //标记,避免同套题重复记数
            //只要是用学生stu数组里的数据,记得-1,因为数组从0开始
            if (!*(mark + j * k + *(stu + i * m + j)-1))
            {
                *(mark + j * k + *(stu + i * m + j)-1) = 1;
                *(ans + *(stu + i * m + j) - 1)+=1;
            }
        }
    }
    for (i = 0; i < k; i++)
    {
        cout << *(ans + i) << " ";
    }
    return 0;
}

欢迎指正与分享,谢谢!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值