AtCoder Beginner Contest 169

入口

A - Multiplication 1

#include
using namespace std;
int main()
{
	LL a,b;
	cin>>a>>b;
	cout<<a*b<<endl;
	return 0;
}

B - Multiplication 2 (精度)

给一堆 ai >= 0 让你累乘,若结果大于1e18 输出 -1 ,否则输出结果;
当时写的花里胡哨的,换了几种方法也过不去,可能写的比较乱,,,服了;
其实可以使用__int128_t 有128位,可以省去不少麻烦,虽然C++没有它的输入输出函数,但是在运算过程中还是可以用的;

#include
using namespace std;
typedef long long LL;

int main()
{
	LL n;cin>>n;
	vector<LL> a(n);
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0;i<n;i++){
		if(a[i]==0){
			cout<<0<<"\n";
			return 0;
		}
	}
	LL ans=1,k = 1e18;
	for(int i=0;i<n;i++){
		if(a[i]>k/ans){		//赛中也差不多这么写,后来看看就只wa了第一个测试点,代码还是写清爽些比较好
			ans = -1;break;
		}
		ans*=a[i];
	}
	cout<<ans<<endl;
	return 0;
}

C - Multiplication 3 (精度)

两数相乘,其中 0 <= a <=10e15, 0 <= b < 10,b位带两位小数的浮点数,输出 a*b。
很明显的卡精度,还好以前踩过坑,直接给秒了。
除了以下的 scanf 方法,再提供另外一种方法,就是给浮点数补充一下损失的精度,可以根据精度要求再加上一个小数;

#include
using namespace std;
typedef long long LL;
int main()
{
	LL a,b,c;
	scanf("%lld%lld.%lld",&a,&b,&c);
	LL ans = a*b;
	LL t = a*c;
	ans+=t/100;
	cout<<ans<<endl;
	return 0;
}

D - Div Game (唯一分解)

读懂题意后,其实就是个唯一分解定理;分解后把各个质数的指数拆分成尽量多的整数的和,那么1、2、3……是最优的贪心拆法。

#include
using namespace std;
typedef long long LL;
LL p[100],cnt;

int main()
{
	LL n;
	cin>>n;
	for(LL i=2;i*i<=n;i++){
		while(n%i==0){
			p[cnt]++;
			n/=i;
		}
		if(p[cnt]) cnt++;
	}
	if(n>1) p[cnt++]++;
	LL ans=0;
	for(int i=0;i<cnt;i++){
		int j=1;
		while(p[i]>=0){
			p[i]-=j;
			j++;
			ans++;
		}
		ans--;
	}
	cout<<ans<<endl;
	return 0;
}

E - Count Median **(思维)

已知 n 对[ ai , bi ],取n个 xi ,且 ai <= xi <=bi 。问这n个数能有多少不同的中位数取值。特别地,当n为偶数时,中位数是中间两个数的平均数(可能有0.5的出现)。
可以证明,最小和最大的中位数中间的所有可能的中位数都是一定可以取到的。
所以找到找到最大最小中位数后直接计算个数即可。

#include
using namespace std;
const int N = 2e5+7;

int n;
int a[N],b[N];

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
	sort(a+1,a+1+n);
	sort(b+1,b+1+n);
	if(n&1) cout<< b[n+1>>1] - a[n+1>>1] +1<<endl; //闭区间内整数个数 
	else cout<<b[n/2]+b[n/2+1]-a[n/2]-a[n/2+1] + 1<<endl; //闭区间内整数个数加上带0.5的小数个数 
	return 0;
}

你可能感兴趣的:(AtCoder)