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

A - Discount

题目大意

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

1 ≤ B < A ≤ 1 0 5 1\le B<A\le 10^5 1B<A105

输入格式

A   B A~B A B

输出格式

输出答案(不加%)。最大允许误差为 1 0 − 2 10^{-2} 102

样例

A A A B B B 输出
100 100 100 80 80 80 20.0 20.0 20.0
7 7 7 6 6 6 14.285714 14.285714 14.285714
99999 99999 99999 99998 99998 99998 0.0010000100001 0.0010000100001 0.0010000100001

分析

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

代码

#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。
N N N家商店售卖Play Snuke。Takahashi从家到第 i i i个商店需要 A i A_i Ai分钟,这家商店的卖价是
P i P_i Pi元且库存 X i X_i Xi件Play Snuke。
现在,Takahashi想要去这 N N N家店中的某一家并且买一个Play Snuke。
但是,每家店的Play Snuke都会在第 0.5 , 1.5 , 2.5 , … 0.5,1.5,2.5,\dots 0.5,1.5,2.5,分钟被买掉一个。
判断Takahashi到底能不能买到Play Snuke。如果能,请输出他最少要花的钱。

1 ≤ N ≤ 1 0 5 1\le N\le 10^5 1N105
1 ≤ A i , P i , X i ≤ 1 0 9 1\le A_i, P_i, X_i\le 10^9 1Ai,Pi,Xi109

输入格式

N N N
A 1   P 1   X 1 A_1~P_1~X_1 A1 P1 X1
⋮ \vdots
A N   P N   X N A_N~P_N~X_N AN PN XN

输出格式

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

样例

样例输入1

3
3 9 5
4 8 5
5 7 5

样例输出1

8

Takahashi可以去 2 2 2号商店,需要花 8 8 8元。

样例输入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

分析

对于第 i i i个商店,如果 X i > A i X_i>A_i Xi>Ai,则Takahashi到达时商品没有卖光,这时取最大的 P i P_i Pi输出即可。如果没有 i i i符合条件 X i > A i X_i>A_i Xi>Ai,则输出-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

题目大意

给你一个整数 N N N。有多少个在 1 1 1~ N N N之间的整数不能表示为 a b a^b ab a a a b b b都是不少于 2 2 2的整数)?

1 ≤ N ≤ 1 0 10 1\le N\le 10^{10} 1N1010

输入格式

N N N

输出格式

输出答案。

样例

N N N 输出
8 8 8 6 6 6
100000 100000 100000 99634 99634 99634

分析

其实能表示为 a b a^b ab的整数并不多。我们只要枚举所有的 a a a 2 ≤ a ≤ N 2\le a\le \sqrt N 2aN ),再把它的不超过 N N N的所有整数次方放入一个set中(去重),再用 N − 最终set中的元素个数 N-\text{最终set中的元素个数} N最终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查看

输入格式

K K K
S S S
T T T

输出格式

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

样例

K K K S S S T T T 输出
2 2 2 1144# 2233# 0.4444444444444 0.4444444444444 0.4444444444444
2 2 2 9988# 1122# 1.0 1.0 1.0
6 6 6 1122# 2228# 0.0019323671498 0.0019323671498 0.0019323671498
1 0 5 10^5 105 3226# 3597# 0.6296297942426 0.6296297942426 0.6296297942426

分析

(参考AtCoder官方题解
对于每一对 ( x , y ) (x, y) (x,y),Takahashi有卡牌 x x x且Aoki有卡牌 y y y的总组合数为:
{ C x C y ( x ≠ y ) C x ( C x − 1 ) ( x = y ) \begin{cases} C_xC_y & (x \ne y)\\ C_x(C_x - 1) & (x = y)\\ \end{cases} { CxCyCx(Cx1)(x=y)(x=y)
枚举每一对 ( x , y ) (x, y) (x,y),拿最终的结果除以 ( 9 K − 8 ) ( 9 K − 9 ) (9K - 8)(9K - 9) (9K8)(9K9)即可。

代码

#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;
}

猜你喜欢

转载自blog.csdn.net/write_1m_lines/article/details/114413985