http://codeup.cn/problem.php?cid=100000582&pid=1
題目
題目描述
先輸入一組數,然後輸入其分組,按照分組統計出現次數並輸出,參見樣例。
輸入
輸入第一行表示樣例數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}
分析
1.變量
全局變量
【題目條件n<100那麼n<maxn,若設數組則有0—101,用101做Link】
const int maxn=102;
int n,m;
對於每一組樣例
未處理的數Num,去重排序過後的數NumUi
tmp暫存的分組號,去重排序過後的分組號Class
按照分組號在分組號的一位數組中插入數(未累積重複出現的次數)table[分組號][Link]
Link的解釋:其中table[tmp][maxn - 1]++使得隊尾元素【101】(n不超過100必不會達到101)在不斷變大,作爲下一個要插入的數組的下標以及當前數組中的數的個數
int Num[maxn]={},tmp,table[maxn][maxn]={};
set<int>NumUi;
set<int>Class;
2.輸入
for(int i=0;i<n;i++){
//寫入未處理的Num數,以便對應table;
//寫入STL容器NumUI即爲去重排序過後的數,表示{?=%d}
scanf("%d",&Num[i]);
NumUi.insert(Num[i]);
}
for(int i=0;i<n;i++){
//tmp爲暫存的分組號
//寫入STL容器Class即爲去重排序過後的分組號
//按照分組號在分組號的一位數組中插入數(未累積重複出現的次數)
//table[tmp][maxn - 1]++使得隊尾元素【101】(n不超過100必不會達到101)在不斷變大,作爲下一個要插入的數組的下標以及當前數組中的數的個數
scanf("%d",&tmp);
Class.insert(tmp);
table[tmp][table[tmp][maxn-1]++]=Num[i];
}
3.輸出
3.0累積重複出現的次數
//tmp爲暫存的數在該分組中的數量
tmp=0;
for(int i=0;i<100;i++){//注意上限不是maxn是100(n不超過100)
if(table[*cls][i]==*num)
tmp++;
}
printf("%d",tmp);
3.1
因爲不知道如何找倒數第二個元素;
所以只能這麼寫,判定是否爲第一個來寫,
每一個的最後再}\n
or(set<int>::iterator cls=Class.begin();cls!=Class.end();cls++){
printf("%d={",*cls);
for(set<int>::iterator num=NumUi.begin();num!=NumUi.end();num++){
printf("%s%d=",num==NumUi.begin()?"":",",*num);
//tmp爲暫存的數在該分組中的數量
tmp=0;
for(int i=0;i<100;i++){//注意上限不是maxn是100(n不超過100)
if(table[*cls][i]==*num)
tmp++;
}
printf("%d",tmp);
}
printf("}\n");
}
AC代碼
#include<bits/stdc++.h>
using namespace std;
const int maxn=102;
int n,m;
int main()
{
while(scanf("%d",&m)!=EOF)
{
while(m--)
{
scanf("%d",&n);
int Num[maxn]={},tmp,table[maxn][maxn]={};
set<int>NumUi;
set<int>Class;
for(int i=0;i<n;i++){
//寫入未處理的Num數,以便對應table;
//寫入STL容器NumUI即爲去重排序過後的數,表示{?=%d}
scanf("%d",&Num[i]);
NumUi.insert(Num[i]);
}
for(int i=0;i<n;i++){
//tmp爲暫存的分組號
//寫入STL容器Class即爲去重排序過後的分組號
//按照分組號在分組號的一位數組中插入數(未累積重複出現的次數)
//table[tmp][maxn - 1]++使得隊尾元素【101】(n不超過100必不會達到101)在不斷變大,作爲下一個要插入的數組的下標以及當前數組中的數的個數
scanf("%d",&tmp);
Class.insert(tmp);
table[tmp][table[tmp][maxn-1]++]=Num[i];
}
for(set<int>::iterator cls=Class.begin();cls!=Class.end();cls++){
printf("%d={",*cls);
for(set<int>::iterator num=NumUi.begin();num!=NumUi.end();num++){
printf("%s%d=",num==NumUi.begin()?"":",",*num);
//tmp爲暫存的數在該分組中的數量
tmp=0;
for(int i=0;i<100;i++){//注意上限不是maxn是100(n不超過100)
if(table[*cls][i]==*num)
tmp++;
}
printf("%d",tmp);
}
printf("}\n");
}
}
}
return 0;
}
寫題過程中的錯誤
錯誤代碼
以id[1000100]作爲hash表;1000100爲表長;H(key)=組號*100+數
數的大小沒說在100以內,100010仍有可能會有數組越界或者重複
#include<bits/stdc++.h>
using namespace std;
int n,m,id[1000100]= {};
void hash(int x,int y,int num[])//組號*100+數
{
num[x*100+y]++;
return;
}
int main()
{
while(scanf("%d",&m)!=EOF)
{
while(m--)
{
scanf("%d",&n);
int x,y[n];
memset(id,0,sizeof(id));
set<int>fz;
set<int>zno;
for(int i=0; i<n; i++)
{
scanf("%d",&y[i]);
fz.insert(y[i]);
}
for(int i=0; i<n; i++)
{
scanf("%d",&x);
zno.insert(x);
hash(x,y[i],id);
}
for(set<int>::iterator it=zno.begin(); it!=zno.end(); it++)
{
printf("%d={",*it);
for(set<int>::iterator its=fz.begin(); its!=fz.end(); its++)
printf("%s%d=%d",its==fz.begin()?"":",",*its,id[*it*100+*its]);
printf("}\n");
}
}
}
return 0;
}