A.B比较简单,题解就不放了,主要想说下C的几种做法
C-Ringo’s Favorite Numbers 2
题目链接
本题我在比赛中用的是类似埃氏筛的思想,用一个vis[]数组来标记。但是赛后看队友的做法和editorial提供的做法时,感觉有所启发,故记录一下,感觉还蛮有意思的,主要想分享一下一步步优化的过程。具体做法见我的代码。
#include<bits/stdc++.h>
using namespace std;
/*
//1.法1:埃氏筛的思想,我的做法,核心是统计每一类的个数,然后用排列组合公式
const int N = 2e5+10;
typedef long long LL;
LL ans;
int a[N];
bool vis[N];
int main() {
int n;
cin>>n;
for(int i = 1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
if(vis[i])continue;//加了vis[]数组标记已经访问过了
LL cnt=0;
for(int j=i+1;j<=n;j++){
if((a[i]-a[j])%200==0){
cnt++;
vis[j]=true;
}
}
ans+=cnt*(cnt+1)/2;
}
cout<<ans<<endl;
return 0;
}
*/
//法2:核心思想也是统计每一类的个数 但是这个是手动模拟了一下加的过程
const int N=2e5+10;
typedef long long LL;
LL ans;
int a[N];
int x;
int main(){
int n;
cin>>n;
//2.1手动模拟组合公式推导的过程 swc的解法和hyb的解法
// for(int i=1;i<=n;i++){
// cin>>x;
// x%=200;
// if(a[x]) ans+=a[x];
// a[x]++;
// }
//2.2进一步优化 editorial提供的解法
for(int i=1;i<=n;i++){
cin>>x;
a[x%200]++;
}
for(int k=0;k<200;k++){
ans+=(LL)a[k]*(a[k]-1)/2;//这里要加LL 不然会爆掉
}
cout<<ans<<endl;
}
运行时间如下:(当然如果用scanf,printf输入输出第二种做法应该是38ms左右,参考hyb的运行时间,我这里给的是cin,cout自己的测试,中间有个WA额是因为没开a[k]*(a[k]-1)没开long long。