洛谷 P1097 【统计数字】 题解
题目背景 警告:数据可能存在加强 题目描述 某次科研调查时得到了nn个自然数,每个数均不超过1500000000(1.5 \times 10^9)1500000000(1.5×10 9 )。已知不相同的数不超过1000010000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。 输入输出格式 输入格式: 共n+1n+1行。 第一行是整数nn,表示自然数的个数; 第22至n+1n+1每行一个自然数。 输出格式: 共mm行(mm为nn个自然数中不相同数的个数),按照自然数从小到大的顺序输出。 每行输出22个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。 输入输出样例 输入样例#1: 8 2 4 2 4 5 100 2 100 输出样例#1: 2 3 4 2 5 1 100 2 说明 40%的数据满足:1≤n≤1000 80%的数据满足:1≤n≤50000 100%的数据满足:1≤n≤200000,每个数均不超过1500000000(1.5×109)
首先,要注意这道题的数据范围
其次,个人认为本题解是最适合萌新的
看别的大佬都用 map 或 set 之类的怪东西,个人认为一个一维数组就完全可以AC掉这道题
我感觉我的代码应该算快的了用了321ms 1448KB
先用一个快排
然后进行以下处理(解释都在核心代码里了~QAQ~)
for(int i=1;i<=n;i++) { int sum1=0;//看看有几个数是相同的 for(int j=i;j<=n;j++)//从i一直找 { if(s[j]==s[j+1])//如果相同 { sum1++;//计数器加一 } else { break;//不然就直接退出,避免出现另外两个数相同的情况 } } cout<<s[i]<<" "<<sum1+1<<endl;//输出 i+=sum1;//相当于将一样的数算在一起,然后直接到下一个不相等的数的位置 }
以下是代码:
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<algorithm> using namespace std; int s[200001]; int main() { int n; int maxn=-1; cin>>n; for(int i=1;i<=n;i++) { cin>>s[i]; } sort(s+1,s+n+1); for(int i=1;i<=n;i++) { int sum1=0; //cout<<s[i]<<endl; for(int j=i;j<=n;j++) { if(s[j]==s[j+1]) { sum1++; } else { break; } } cout<<s[i]<<" "<<sum1+1<<endl; i+=sum1; } return 0; }