《算法笔记》codeup_100000582_B

思路:

设置两个一维数组分别保存数和组号。设置一个二维数组,第一维的下标i表示组号,第二维的下标j表示数的大小,数组的元素值表示第i组的j数的个数,这应用散列的思想。遍历每一组数据完成二维数组的赋值。然后分别对两个一维数组进行排序。最后分别遍历每一个组合不同且数不同的数据,访问这些数据的组号和数作为下标的二维数组元素的值,得到每个不同数据的个数并输出。

解答:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int main() {
	int test_num;
	while (scanf("%d", &test_num)!=EOF) {
		while (test_num--) {
			int data_num;
			scanf("%d", &data_num);
			int num[110];
			int team[110];
			for (int i = 0; i <= data_num - 1; i++) {
				scanf("%d", &num[i]);
            }

            // 每一个不同的数的个数都保存到二维数组中
			for (int i = 0; i <= data_num - 1; i++) {
				scanf("%d", &team[i]);
			}

			// 获取num数组和team数组里面最大的数
            int max_num = num[0];
            int max_team = team[0];
			for (int i = 1; i <= data_num - 1; i++) {
                if(num[i] > max_num)
                    max_num = num[i];
                if(team[i] > max_team)
                    max_team = team[i];
			}

			
			int a[max_team + 1][max_num + 1];   // 维度的下标大小只能取到初始化设置的维度的大小-1,如max_num为8但第二维大小是8时下标只能取到7
			memset(a, 0, sizeof(a));

			for (int i = 0; i <= data_num - 1; i++) {
				a[team[i]][num[i]]++;
			}

            // 不同数的个数前面已保存,num数组和team数组不再需要一一对应,排序后只用来提供各个组号和数
			sort(num, num + data_num);
			sort(team, team + data_num);
            
            // 遍历每一个不同的数,不同指组不同或数的大小不同
			int prev_team = team[0];                              // prev_team表示上一次的组号
			for (int i = 0; i <= data_num - 1; i++) {             // 遍历所有组,组数不超过data_num
                if (i == 0 || (i > 0 && team[i] != prev_team)) {  // 如果i指向第一个或一个不同的组,也就是跳过重复的组
					printf("%d={", team[i]);                      // 打印组号

					int prev_prev = num[0];                        // prev_prev表示上一次的数
					for (int j = 0; j <= data_num - 1; j++) {     // 遍历所有数,数的格式不超过data_num
						if (j == 0 || (j > 0 && num[j] != prev_prev)) {    // 如果如果j指向第一个或一个大小不同的数,也就是跳过重复的数
							printf("%d=%d", num[j], a[team[i]][num[j]]);  // 打印组号为i的j数及其个数
							
							if (num[j] != num[data_num - 1])              // 如果当前的数不是最后的数则输出逗号
                                printf(",");
						}

						if (prev_prev != num[j])                           // 如果当前的数与上一次的不同,则更新
                            prev_prev = num[j];
					}

					printf("}\n");

					if (prev_team != team[i])                      // 如果当前的组号与上一次的不同,则更新
                        prev_team = team[i];
				}
			}
		}
	}
	return 0;
}

坑:

  1. 在vscode上成功运行,但提交codeup后出现编译错误0,查看详情提示variable-sized object may not be initialized,查询后得知是使用变量定义数组大小时,不能同时进行定义和初始化。但我看到好几个人的答案都是这么做的,不知道怎么回事……

    			int a[max_team][max_num] = { 0 };
    			a = { 0 };

    这种代码仍然会提示“表达式必须是可修改的左值错误”,因为a保存的是二维数组的地址,是一个常量,不能修改。最后使用memset进行二维数组的初始化解决了问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值