GoodCoder666的个人博客

Caddi Programming Contest 2021 (AtCoder Beginner Contest 193) A~D 题解

2021-03-08 · 7 min read
C++ 算法竞赛

A - Discount

题目大意

一件商品原价为AA元,现价为BB元,现价优惠了百分之几?

1B<A1051\le B<A\le 10^5

输入格式

A BA~B

输出格式

输出答案(不加%)。最大允许误差为10210^{-2}

样例

AA BB 输出
100100 8080 20.020.0
77 66 14.28571414.285714
9999999999 9999899998 0.00100001000010.0010000100001

分析

这里答案可以直接使用ABA\frac{A-B}{A}求得结果。

代码

#include <cstdio>
#include <tuple>
using namespace std;

int main()
{
	int a, b;
	scanf("%d%d", &a, &b);
	printf("%.6lf", (a - b) * 100.0 / a);
	return 0;
}

B - Play Snuke

题目大意

Takahashi想要买一件商品,它叫Play Snuke。
NN家商店售卖Play Snuke。Takahashi从家到第ii个商店需要AiA_i分钟,这家商店的卖价是
PiP_i元且库存XiX_i件Play Snuke。
现在,Takahashi想要去这NN家店中的某一家并且买一个Play Snuke。
但是,每家店的Play Snuke都会在第0.5,1.5,2.5,0.5,1.5,2.5,\dots分钟被买掉一个。
判断Takahashi到底能不能买到Play Snuke。如果能,请输出他最少要花的钱。

1N1051\le N\le 10^5
1Ai,Pi,Xi1091\le A_i, P_i, X_i\le 10^9

输入格式

NN
A1 P1 X1A_1~P_1~X_1
\vdots
AN PN XNA_N~P_N~X_N

输出格式

如果Takahashi能买到Play Snuke,输出他最少要花的钱数;否则,输出-1

样例

样例输入1

3
3 9 5
4 8 5
5 7 5

样例输出1

8

Takahashi可以去22号商店,需要花88元。

样例输入2

3
5 9 5
6 8 5
7 7 5

样例输出2

-1

无论Takahashi去哪个商店,到达时Play Snuke都卖光了,因此输出-1

样例输入3

10
158260522 877914575 602436426
24979445 861648772 623690081
433933447 476190629 262703497
211047202 971407775 628894325
731963982 822804784 450968417
430302156 982631932 161735902
880895728 923078537 707723857
189330739 910286918 802329211
404539679 303238506 317063340
492686568 773361868 125660016

样例输出3

861648772

分析

对于第ii个商店,如果Xi>AiX_i>A_i,则Takahashi到达时商品没有卖光,这时取最大的PiP_i输出即可。如果没有ii符合条件Xi>AiX_i>A_i,则输出-1

代码

#include <cstdio>
#define maxn 100005
#define INF 2147483647
using namespace std;

int main()
{
	int n, ans = INF;
	scanf("%d", &n);
	for(int i=0; i<n; i++)
	{
		int a, p, x;
		scanf("%d%d%d", &a, &p, &x);
		if(x > a && p < ans)
			ans = p;
	}
	if(ans == INF) puts("-1");
	else printf("%d\n", ans);
	return 0;
}

C - Unexpressed

题目大意

给你一个整数NN。有多少个在11~NN之间的整数不能表示为aba^baabb都是不少于22的整数)?

1N10101\le N\le 10^{10}

输入格式

NN

输出格式

输出答案。

样例

NN 输出
88 66
100000100000 9963499634

分析

其实能表示为aba^b的整数并不多。我们只要枚举所有的aa2aN2\le a\le \sqrt N),再把它的不超过NN的所有整数次方放入一个set中(去重),再用N最终set中的元素个数N-\text{最终set中的元素个数}即可。

代码

#include <cstdio>
#include <cmath>
#include <set>
using namespace std;

using LL = long long;
set<LL> s;

int main()
{
	LL n;
	scanf("%lld", &n);
	LL tmp = sqrt(n);
	for(LL a=2; a<=tmp; a++)
	{
		LL res = a; // res = a ^ b
		while((res *= a) <= n)
			s.insert(res);
	}
	printf("%lld\n", n - s.size());
	return 0;
}

D - Poker

题目大意

略,请自行前往AtCoder查看

输入格式

KK
SS
TT

输出格式

输出一行,即Takahashi的胜率(不要使用百分数,请使用0011之间的小数)。最大允许误差10510^{-5}

样例

KK SS TT 输出
22 1144# 2233# 0.44444444444440.4444444444444
22 9988# 1122# 1.01.0
66 1122# 2228# 0.00193236714980.0019323671498
10510^5 3226# 3597# 0.62962979424260.6296297942426

分析

(参考AtCoder官方题解
对于每一对(x,y)(x, y),Takahashi有卡牌xx且Aoki有卡牌yy的总组合数为:

{CxCy(xy)Cx(Cx1)(x=y)\begin{cases} C_xC_y & (x \ne y)\\ C_x(C_x - 1) & (x = y)\\ \end{cases}

枚举每一对(x,y)(x, y),拿最终的结果除以(9K8)(9K9)(9K - 8)(9K - 9)即可。

代码

#include <cstdio>
using namespace std;

using LL = long long;

char s[7], t[7];

int score(const char* cards)
{
	int cnt[10];
	for(int i=0; i<10; i++) cnt[i] = i;
	for(int i=0; i<5; i++)
		cnt[cards[i] - '0'] *= 10;
	int res = 0;
	for(int x: cnt) res += x;
	return res;
}

int main()
{
	int k;
	scanf("%d%s%s", &k, s, t);
	int cnt[10];
	for(int i=1; i<10; i++) cnt[i] = k;
	for(int i=0; i<4; i++)
		cnt[s[i] - '0'] --,
		cnt[t[i] - '0'] --;
	LL win = 0LL;
	for(int x=1; x<10; x++)
		if(cnt[x])
		{
			s[4] = '0' + x;
			int sscore = score(s);
			for(int y=1; y<10; y++)
				if(cnt[y])
				{
					t[4] = '0' + y;
					if(sscore > score(t))
						win += cnt[x] * LL(cnt[y] - (x == y));
				}
		}
	LL tmp = 9LL * k - 8LL;
	printf("%.8lf\n", double(win) / tmp / double(tmp - 1LL));
	return 0;
}