分组统计

问题 B: 分组统计时间限制: 1 Sec 内存限制: 32 MB

提交: 416 解决: 107

[提交][状态][讨论版][命题人:外部导入]

题目描述

先输入一组数,然后输入其分组,按照分组统计出现次数并输出,参见样例。

输入

输入第一行表示样例数m,对于每个样例,第一行为数的个数n,接下来两行分别有n个数,第一行有n个数,第二行的n个数分别对应上一行每个数的分组,n不超过100。

输出

输出m行,格式参见样例,按从小到大排。

样例输入

1
7
3 2 3 8 8 2 3
1 2 3 2 1 3 1

样例输出

1={2=0,3=2,8=1}
2={2=1,3=0,8=1}
3={2=1,3=1,8=0}

思考

http://codeup.cn/problem.php?cid=100000582&pid=1

这个是典型的哈希算法了。

这个样例是统计每组数字里面各数字(出现在第一行的数字,这一次是3,2,8)的个数。

所以每一组数字要个数组3,记录2,3,8的个数

先搞一个在n个数字第一次出现时的数组num,记录那些数字出现了,出现了几次,以该数字为下标的数组值++,那这个数组大小应该是很大的啊 。

再来就是分组了,再来一个数组zu,以上一行出现过数字为下标,值为所分的组。

n不超过100。怎么表示这种性质呢?结构体?一个整型,记录其在第一行的n个数里的出现次数,再来一个数组,记录自己在不同组的出现次数。

组数肯定要小于n

本地实现

这问题几个月之前就遇到过了。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
//#include <limits.h>
#define maxn 10005
int cmp(const void*a, const void*b){
return *(int*)a - *(int*)b;//升序
}
int main(){
int m;
while(scanf("%d", &m) != EOF){
while(m--){
int n;
scanf("%d", &n);
int cishu[maxn][n+1]= {0};
//int temp[n+1] = INT_MAX;
int temp[n+1] = {0};
for(int i = 1; i <= n; i++){
scanf("%d", &temp[i]);
cishu[temp[i]][0]++;//将第一行数读入数组temp,并且在相应行第0列记录出现在第一行出现次数
}
int zu[n+1] = {0}, num = 0, kzu[n+1] = {0};
for(int i = 1; i <= n; i++) {
scanf("%d",&zu[i]);
kzu[zu[i]]++;
cishu[temp[i]][zu[i]]++;
}
/*二维数组里行代表这个数,列代表该行对应数在某组里出现的次数*/
for(int i = 1; i <= n; i++) {
if(kzu[i] > 0)
num++;
}
//num记录分的组的个数
/*该对第一行的n个数按大小排序了*/
qsort(temp+1, n, sizeof(temp[0]), cmp);
/*for(int i = 1; i <= n; i++){
printf("%d\n", temp[i]);
}//排序正确*/
/*剔除重复项,建立新数组*/
int newtemp[n+1], newxu = 2;
newtemp[1] = temp[1];
for(int i = 2; i <= n; i++) {
if(temp[i] != temp[i-1])//if语句的括号后面跟分号,编译器竟然没error
newtemp[newxu++] = temp[i];
}
/*for(int i = 1; i < newxu; i++){
printf("%d\n", newtemp[i]);
}//剔除重复项,新数组正确*/
for(int j = 1; j <= num; j++) {
printf("%d={", j); //第j组
for(int i = 1; i < newxu; i++){
printf("%d=%d", newtemp[i], cishu[newtemp[i]][j]);
if(i < newxu-1)
printf(",");
}
printf("}\n");
}
}
}
return 0;
}

别人的代码1-二维数组

s066 Problem B 分组统计 - CSDN博客 https://blog.csdn.net/fantasydreams/article/details/79114487

#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
const int MaxN = 102;
int main()
{
#ifdef _DEBUG
ifstream cin("data.txt");
#endif // _DEBUG
//利用链表散列进行统计,这里用二维数组模拟
int m, n;
while (cin >> m)
{
while (m--)
{
int Table[MaxN][MaxN] = {0}, classFlag[MaxN] = {false}, Class[MaxN], ClaN = 0, Num[MaxN], tmp, NumUi[MaxN], N = 0;
cin >> n;
for (int i = 0; i < n; ++i)
cin >> Num[i];//读入第一行所有数
for (int i = 0; i < n; ++i)
{
cin >> tmp;
if (!classFlag[tmp])
{
classFlag[tmp] = true;
Class[ClaN++] = tmp;//该组的序号第一次出现时,记录进来
}
Table[tmp][Table[tmp][MaxN - 1]++] = Num[i];//建立这个表,第几组就是第几行 ,避免了数组越界
}//该数是第几组存进第几行的,存进哪一列呢?从第1列,开始存,该行最后一列记录了该组的数字个数
sort(Class, Class + ClaN);//组序号排序 ,ClaN记录组的个数
sort(Num, Num + n);//第一行数字排序
/*剔除重复项,建立新数组*/
for (int i = 0; i < n; ++i)
{
if (N == 0 || Num[i] != NumUi[N-1])
{
NumUi[N++] = Num[i];
}
} for (int k = 0; k < ClaN; ++k)
{
printf("%d={", Class[k]);/*组号*/
for (int h = 0; h < N; ++h)/*按第一行数字顺序*/
{ /*查询,如果出现相同的,则数字加1*/
int c = 0, j = 0;
for (; j < Table[Class[k]][MaxN - 1]; ++j)
{
if (Table[Class[k]][j] == NumUi[h])
++c;
}
printf("%d=%d", NumUi[h], c);
if (h < N-1)
printf(",");
}
printf("}\n");
}
}
} #ifdef _DEBUG
cin.close();
system("pause");
#endif // _DEBUG return 0;
}

别人的代码2-散列

C/C++[codeup 2066]分组统计 - CSDN博客 https://blog.csdn.net/u014281392/article/details/80841162

C++ STL算法系列4---unique , unique_copy函数 - 夏雪冬日 - 博客园 https://www.cnblogs.com/heyonggang/archive/2013/08/07/3243477.html

#include <iostream>
#include <algorithm> //max_element,unique_copy
#include <cstring>
#include <vector>
using namespace std;
int main() {
int M;
while(cin>>M) {
while (M--) {
int N; //输入数据的个数
cin >> N;
int nums[N], cls[N]; //数据和类别
for (int i = 0; i < N; i++)
cin >> nums[i];
for (int i = 0; i < N; i++)
cin >> cls[i];
// 数据的最大值和类别
int max_cls = *max_element(cls, cls + N);
int max_num = *max_element(nums, nums + N);
// hash二维数组计数
int hashTable[max_cls + 1][max_num + 1];
// 全0初始化
memset(hashTable, 0, sizeof(hashTable));
for (int i = 0; i < N; i++)
hashTable[cls[i]][nums[i]]++;
//类排序去重
vector<int> v2;
sort(cls, cls+N);
unique_copy(cls, cls + N, back_inserter(v2));
//nums排序去重
vector<int> v;
sort(nums, nums + N);
unique_copy(nums, nums + N, back_inserter(v));
for (int i = 0; i < v2.size(); i++) {
cout << v2[i] << "={";
for (int j = 0; j < v.size(); j++) {
cout << v[j] << '=' << hashTable[v2[i]][v[j]];
if (j < v.size() - 1) cout << ',';
}
cout << '}' << endl;
}
}
}
return 0;
}

这里比较重要的是,取得容器内最大值,防止二维数组越界问题。

防止越界的散列

C++ STL之min_element()与max_element()(取容器中的最大最小值) - Angel_Kitty - 博客园 https://www.cnblogs.com/ECJTUACM-873284962/p/6734225.html

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b)
{
return a<b;
// return a>b;
}
int main()
{
int num[]={2,3,1,6,4,5};
cout<<"最小值是 "<<*min_element(num,num+6)<<endl; //默认升序
cout<<"最大值是 "<<*max_element(num,num+6)<<endl;
cout<<"最小值是 "<<*min_element(num,num+6,cmp)<<endl; //可以修改为 return a>b;改降序
cout<<"最大值是 "<<*max_element(num,num+6,cmp)<<endl;
return 0;
}

关于c语言初始化的问题

C/C++数组初始化的一些误区 - CSDN博客 https://blog.csdn.net/u014417133/article/details/77185009

也就是说,要置零,使用memset最好了。

memset(cur,0,sizeof(cur))

AC代码

#include <iostream>
#include <algorithm> //max_element,unique_copy
#include <cstring>
#include <vector>
using namespace std;
int main() {
int M;
while(cin>>M) {
while (M--) {
int N; //输入数据的个数
cin >> N;
int nums[N], cls[N]; //数据和类别
for (int i = 0; i < N; i++)
cin >> nums[i];
for (int i = 0; i < N; i++)
cin >> cls[i];
// 数据的最大值和类别
int max_cls = *max_element(cls, cls + N);
int max_num = *max_element(nums, nums + N);
// hash二维数组计数
int hashTable[max_cls + 1][max_num + 1];
// 全0初始化
memset(hashTable, 0, sizeof(hashTable));
for (int i = 0; i < N; i++)
hashTable[cls[i]][nums[i]]++;
//类排序去重
vector<int> v2;
sort(cls, cls+N);
unique_copy(cls, cls + N, back_inserter(v2));
//nums排序去重
vector<int> v;
sort(nums, nums + N);
unique_copy(nums, nums + N, back_inserter(v));
for (int i = 0; i < v2.size(); i++) {
cout << v2[i] << "={";
for (int j = 0; j < v.size(); j++) {
cout << v[j] << '=' << hashTable[v2[i]][v[j]];
if (j < v.size() - 1) cout << ',';
}
cout << '}' << endl;
}
}
}
return 0;
}

问题 B: 分组统计的更多相关文章

  1. Linq to SQL 语法查询(链接查询,子查询 & in操作 & join,分组统计等)

    Linq to SQL 语法查询(链接查询,子查询 & in操作 & join,分组统计等) 子查询 描述:查询订单数超过5的顾客信息 查询句法: var 子查询 = from c i ...

  2. Dev用于界面按选中列进行分组统计数据源(实用技巧)

    如果有用U8的可以明白这个功能就是模仿他的统计功能.我不过是把他造成通用的与适应于DEV的. (效率为6000条数据分组统计时间为3秒左右分组列过多5秒.1000条以下0.几秒,500条下0.00几秒 ...

  3. DataTable、List使用groupby进行分组和分组统计;List、DataTable查询筛选方法

    DataTable分组统计: .用两层循环计算,前提条件是数据已经按分组的列排好序的. DataTable dt = new DataTable(); dt.Columns.AddRange(new ...

  4. 每日学习心得:CustomValidator验证控件验证用户输入的字符长度、Linq 多字段分组统计、ASP.NET后台弹出confirm对话框,然后点击确定,执行一段代码

    2013-9-15 1.    CustomValidator验证控件验证用户输入的字符长度 在实际的开发中通常会遇到验证用户输入的字符长度的问题,通常的情况下,可以写一个js的脚本或者函数,在ASP ...

  5. ORACLE的分组统计之ROLLUP(一)

    Oracle 9i以后,扩展了group by 的功能,能够满足大部分多维数据的分析统计功能,主要表现: 1. rollup,cube,grouping sets 扩展group by字句提供了丰富的 ...

  6. XtraGrid使用心得(折叠式主细档、分组统计)

    XtraGrid的关键类就是:GridControl和GridView.GridControl本身不显示数据,数据都是显示在GridView/CardView/XXXXView中.GridContro ...

  7. Oracle按不同时间分组统计

    Oracle按不同时间分组统计 Oracle按不同时间分组统计的sql 如下表table1: 日期(exportDate) 数量(amount) -------------- ----------- ...

  8. 使用awk进行日志信息的分组统计

    起因 这是今天我线上出了一个bug,需要查看日志并统计一个我需要的信息出现的频率,可以叫做分组统计. 日志文件部分内容 00:09:07.655 [showcase_backend][topsdk] ...

  9. Mysql 根据时间戳按年月日分组统计

    Mysql 根据时间戳按年月日分组统计create_time时间格式SELECT DATE_FORMAT(create_time,'%Y%u') weeks,COUNT(id) COUNT FROM ...

  10. Mysql中较为复杂的分组统计去重复值

    这是我的代码: 前提是做了一个view:att_sumbase 首先分开统计每天的中午.下午饭点人数,这时需要分别去除中午和下午重复打卡的人.用了记录集的交,嵌套select的知识. 注意不能直接使用 ...

随机推荐

  1. [Windows] 一些简单的CMD命令

    开始菜单中的“运行”是通向程序的快捷途径,输入特定的命令后,即可快速的打开Windows搜索的大部分程序,熟练的运用它,将给我们的操作带来诸多便捷. winver 检查Windows版本 wmimgm ...

  2. Android 中文 API (101) —— AsyncTask

    一.结构 public abstract class AsyncTask extends Object java.lang.Object android.os.AsyncTask<Params, ...

  3. quartz任务调度初次使用记录

    近期公司开发的数据交换系统嵌入了quartz任务调度功能,大概了解了任务调度的整个流程,项目中需要用到它来进行定时任务操作,对数据定时检查以及及时交换. Quartz是OpenSymphony开源组织 ...

  4. Default Bearer, Dedicated Bearer... What exactly is bearer ?

    Default Bearer, Dedicated Bearer... What exactly is bearer ?   While trying to get a better understa ...

  5. idea没有绑远程地址,如何提交到github的空项目

    一 有同事问我怎么提交到github的空项目....这么简单.... 二 1.创建本地的git仓库 选择自己的项目 创建成功 2.添加代码,选中左边的文件,add 3.提交 5.定义远程仓库,不定义的 ...

  6. 学习笔记:MDN的JavaScript

    JavaScript 第一步 什么是JavaScript? 每次当你浏览网页时不只是显示静态信息—— 显示即时更新的内容, 或者交互式的地图,或 2D/3D 图形动画,又或者自动播放视频等,你可以确信 ...

  7. Browser Window

    Window 对象 Window对象表示浏览器中打开的窗口. 如果文档包含框架(iframe或iframe标签),浏览器会被html文档创建一个window对象,并为每个框架创建一个额外的window ...

  8. 虚拟机中Ubuntu安装vmtools

    1.解压vmtools文件为VMWARETO.TGZ VMtools文件一般在系统桌面,如果没有可以点击左上方的"虚拟机-安装VMware Tools"即可出现在桌面,也可以通过U ...

  9. 梦织未来Windows驱动编程 第05课 小结(读取另一驱动,遍历所有驱动)

    读取另一驱动 驱动通过"\\Driver\\XueTr"获取到了XueTr工具的驱动,并Hook了XueTr驱动的分发函数. 具体的驱动代码如下: //FilterDriver.c ...

  10. php使用GD库实现图片水印和缩略图——给图片添加文字水印

    今天呢,就来学习一下在php中使用PD库来实现对图片水印的文字水印方法,不需要PS哦! 首先,准备素材 (1)准备一张图片 (2)准备一张水印(最好是透明的,即背景是白色底) (3)准备一中字体(在电 ...