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()时间复杂度的算法,超时了。
改进
用一个二维数组标记,避免同套题重复记数
#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;
}
欢迎指正与分享,谢谢!