第一次发解题博客,有点啰嗦,见谅
先放题
我的解题思路
1.因为题目中要给出一个n*m的矩阵,所以想到了用二维数组,但是因为忘了动态分配怎么搞的了,这个题数据又不是很大,所以直接建立了一个1001*1001的二维数组,因为表示人数与模拟套数都是从1开始,我写代码时将数组的0位闲置了下来
2.n*m的这个矩阵
(1)如果横着看,每个人的关系就是在第几天做第几套,因为每个人给的天数不一样,也就是每一列的天数不能统一,这样计算起来每列无法统一,每行计算起来要同时考虑列号(第几套)和第几天,非常麻烦,我没有想到解决办法
(2)如果将矩阵竖着看,会发现每列的套数统一了,不管第几个人,只要在这一列中的数据,都是同一套题,我们只需要计算这一套分别在第几天出现了,如第1套在第2.3.5天出现了,那么就可以将2.3.5这几天需要准备的套数分别+1,注意不要重复+1(不管多少人在同一天做一套模拟都只准备一套),此时我们看下一列时,下一列的套数和现在就不一样了;可以直接重复以上操作,直到最后一列,如第1套我们在第3天准备了,到第2列即第2套时在第三天也要准备时,因为套数不同,可以直接+1而不用考虑同一天同一套数不同人多次相加的错误。
下面上我写的代码
#include <stdio.h>
#include <string.h>
int main()
{
int n = 0, m = 0, q = 0;
int arr[1001][1001] = { 0 };//n行m列
int count[1001] = { 0 };//第几天准备几套
int i = 0, j = 0,k = 0,l = 0;
scanf("%d %d %d", &n, &m, &q);//n人m套q天
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
scanf("%d", &arr[i][j]);//输入n行m列
}
}
for (j = 1; j <= m; j++)//按每列计算,表示每人第几天做第j套题
{
int tmp[1001] = { 0 };//存放第j套题第几个人在第几天做
for (i = 1; i <= n; i++)
{
tmp[i] = arr[i][j];//存放第j套题第i个人在第几天做
}
for (k = 1; k <= n; k++)
{
for (l = 1; l <= n; l++)
{
if (k != l && tmp[k] == tmp[l]&&tmp[k]!=0&&tmp[l]!=0)
{
tmp[l] = 0;//将第j套中在一天做的所有人当成一个人,因为这一天只需要准备1套第j套题
}
}
}
for (k = 1; k <= n; k++)
{
if (tmp[k] != 0)//如果tmp数组不为空,说明此时tmp数组中存放的数是唯一的,那么在第tmp[k]天我们需要准备第j套题
{
count[tmp[k]] = count[tmp[k]] + 1;//,如果之前这天不准备,此时就需要准备1套题,之前准备1套,因为套数不同,此时就需要准备两套
}
}
}
for (i = 1; i <= q; i++)
{
printf("%d ", count[i]);//打印第i天教练需要准备count[i]套题
}
return 0;
}
这个代码有点啰嗦,写的时候是直接按思路敲出来的,没有任何优化,欢迎指正与建议