AtCoder Beginner Contest 200 题解

A.B比较简单,题解就不放了,主要想说下C的几种做法

C-Ringo’s Favorite Numbers 2

题目链接
本题我在比赛中用的是类似埃氏筛的思想,用一个vis[]数组来标记。但是赛后看队友的做法和editorial提供的做法时,感觉有所启发,故记录一下,感觉还蛮有意思的,主要想分享一下一步步优化的过程。具体做法见我的代码。

#include
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<

//法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。
AtCoder Beginner Contest 200 题解_第1张图片

你可能感兴趣的:(Atcoder,算法,leetcode,acm,c++,atcoder)