首页 > 其他分享 >AtCoder Beginner Contest 196 A~E 题解

AtCoder Beginner Contest 196 A~E 题解

时间:2024-09-08 21:06:09浏览次数:10  
标签:dots 10 le AtCoder int 题解 196 输出 100

A - Difference Max

题目大意

给定四个整数\(a,b,c\)和\(d\)。
我们要选择两个整数\(x\)和\(y\)(\(a\le x\le b\);\(c\le y\le d\))。输出最大的\(x-y\)。

\(-100\le a\le b\le 100\)
\(-100\le c\le d\le 100\)

输入格式

\(a~~b\)
\(c~~d\)

输出格式

输出最大的\(x-y\)。

样例

\(a\) \(b\) \(c\) \(d\) 输出
\(0\) \(10\) \(0\) \(10\) \(10\)
\(-100\) \(-100\) \(100\) \(100\) \(200\)
\(-100\) \(100\) \(-100\) \(100\) \(200\)

分析

如果要\(x-y\)最大,那么\(x\)要尽可能大、\(y\)要尽可能小。因此,\(x\)取最大值\(b\),\(y\)取最小值\(c\)。所以,我们直接输出\(b-c\)即可。

代码

#include <cstdio>
using namespace std;

int main()
{
	int a, b, c, d;
	scanf("%d%d%d%d", &a, &b, &c, &d);
	printf("%d\n", b - c);
	return 0;
}

B - Round Down

题目大意

给定一个数\(X\),求\(\lfloor X\rfloor\)。

\(0\le X\le 10^{100}\)

输入格式

\(X\)

输出格式

输出\(\lfloor X\rfloor\)。

样例

\(X\) 输出
\(5.90\) \(5\)
\(0\) \(0\)
\(84939825309432908832902189.9092309409809091329\) \(84939825309432908832902189\)

分析

只需找到小数点并将其及后面的数位删去再输出即可。例如:\(5\sout{.90}\)

代码

#include <cstdio>
using namespace std;

int main()
{
	char c;
	while((c = getchar()) != '\n')
	{
		if(c == '.') return 0;
		putchar(c);
	}
	return 0;
}

C - Doubled

题目大意

\(1\)~\(N\)之间有多少个数是另一个正整数重复两遍得来的?

\(1\le N<10^{12}\)

输入格式

\(N\)

输出格式

输出答案。

样例

\(N\) 输出
\(33\) \(3\)
\(1333\) \(13\)
\(10000000\) \(999\)

分析

这道题说白了就是要找到最大的\(X\),使得\(X\)重复两遍不超过\(N\),并输出\(X\)。我们可以使用二分法求出最大的\(X\)。
注意:这里的二分右边界最好设置为\(\sqrt N\),否则一不小心就会溢出!

代码

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

typedef long long LL;

inline bool check(const LL& x, const LL& n)
{
	LL p = 1LL;
	while(p <= x) p *= 10LL;
	return x * p + x <= n;
}

int main()
{
	LL n;
	scanf("%lld", &n);
	LL l = 0LL, r = sqrt(n);
	while(l < r)
	{
		LL mid = l + r + 1LL >> 1LL;
		if(check(mid, n)) l = mid;
		else r = mid - 1;
	}
	printf("%lld\n", l);
	return 0;
}

D - Hanjo

题目大意

有一个\(H\times W\)的地板,请你在地板上铺砖。
有两种地砖:\(a\)和\(b\)。\(a\)地砖有\(A\)个,是\(2\times1\)的可旋转长方形。\(b\)地砖有\(B\)个,是\(1\times1\)的正方形。问要将这个地板正好铺满,总共有多少种铺法?

\(1\le H,W,HW\le 16\)
\(0\le A,B\)
\(2A+B=HW\)

输入格式

\(H~W~A~B\)

输出格式

输出答案。

样例

\(H\) \(W\) \(A\) \(B\) 输出
\(2\) \(2\) \(1\) \(2\) \(4\)
\(3\) \(3\) \(4\) \(1\) \(18\)
\(4\) \(4\) \(8\) \(0\) \(36\)

分析

由于数据范围较小,我们可以用暴力搜索解决这道题。注意,这里搜索时为了避免重复计算,我们每次递归只尝试一个位置,这样还能有效加速。具体请看代码。

代码

#include <cstdio>
#define maxn 20
using namespace std;

bool mat[maxn][maxn];
int h, w, a, b, ans;

inline bool valid(int x, int y)
{
	return !mat[x][y] && x >= 0 && x < h && y >= 0 && y < w;
}

void dfs(int i, int j, int usedA, int usedB)
{
	if((usedA << 1) + usedB == h * w)
	{
		ans ++;
		return;
	}
	if(i == h) return;
	int ni, nj;
	if(j == w - 1) ni = i + 1, nj = 0;
	else ni = i, nj = j + 1;
	if(mat[i][j])
	{
		dfs(ni, nj, usedA, usedB);
		return;
	}
	mat[i][j] = true;
	// Rectangle (A)
	if(usedA < a)
	{
		if(valid(i, j + 1))
		{
			mat[i][j + 1] = true;
			dfs(ni, nj, usedA + 1, usedB);
			mat[i][j + 1] = false;
		}
		if(valid(i + 1, j))
		{
			mat[i + 1][j] = true;
			dfs(ni, nj, usedA + 1, usedB);
			mat[i + 1][j] = false;
		}
	}
	// Square (B)
	if(usedB < b) dfs(ni, nj, usedA, usedB + 1);
	mat[i][j] = false;
}

int main()
{
	scanf("%d%d%d%d", &h, &w, &a, &b);
	dfs(0, 0, 0, 0);
	printf("%d\n", ans);
	return 0;
}

E - Filters

题目大意

给定三个整数序列\(A = (a_1, a_2, \dots, a_N)\)、\(T = (t_1, t_2, \dots, t_N)\)和\(X = (x_1, x_2, \dots, x_Q)\)。
我们如下定义\(N\)个函数\(f_1(x), f_2(x), \dots, f_N(x)\):
\(f_i(x) = \begin{cases} x + a_i & (t_i = 1)\\ \max(x, a_i) & (t_i = 2)\\ \min(x, a_i) & (t_i = 3)\\ \end{cases}\)
对于每个\(i = 1, 2, \dots, Q\),求\(f_N( \dots f_2(f_1(x_i)) \dots )\)。

\(1 \le N,Q \le 2 \times 10^5\)
\(|a_i|,|x_i|\le 10^9\)
\(1 \le t_i \le 3\)

输入格式

\(N\)
\(a_1~t_1\)
\(a_2~t_2\)
\(\vdots\)
\(a_N~t_N\)
\(Q\)
\(x_1~x_2~\dotsx x_q\)

输出格式

输出\(Q\)行。第\(i\)行应该包含\(f_N( \dots f_2(f_1(x_i)) \dots )\)。

样例

样例输入

3
-10 2
10 1
10 3
5
-15 -10 -5 0 5

样例输出

0
0
5
10
10

在这里,\(f_1(x) = \max(x, -10), f_2(x) = x + 10, f_3(x) = \min(x, 10)\),则有:

  • \(f_3(f_2(f_1(-15))) = 0\)
  • \(f_3(f_2(f_1(-10))) = 0\)
  • \(f_3(f_2(f_1(-5))) = 5\)
  • \(f_3(f_2(f_1(0))) = 10\)
  • \(f_3(f_2(f_1(5))) = 10\)

分析

(参考AtCoder官方题解
很容易想到,我们可以直接照做,即分别计算每个\(f_N( \dots f_2(f_1(x_i)) \dots )\)。但是,这样做的时间复杂度是\(\mathcal O(NQ)\),所以肯定会TLE
我们考虑它们的复合函数\(F(x)=f_N( \dots f_2(f_1(x_i)) \dots )\)在图上怎么表示。

  • 当\(t_i=1\),\(f_i\)是将图整体平移的操作;
  • 当\(t_i=2\),\(f_i\)是将图的最小值设为\(a_i\);
  • 当\(t_i=3\),\(f_i\)是将图的最大值设为\(a_i\)。

所以,我们可以得到下图:
F(x)和x的关系

或者说,存在三个数\(a,b,c\)使得\(F(x)=\min(c,\max(b,x+a))\)。
关于\(a,b,c\)的具体计算请看代码。

代码

注意:这里的代码中的\(\infty\)(INF)一定不能直接设为long long的最大值,否则会溢出!

#include <cstdio>
#include <algorithm>
#include <climits>
using namespace std;

typedef long long LL;
const LL INF = LLONG_MAX >> 1LL;

int main()
{
	LL l = -INF, r = INF, add = 0LL;
	int n, q;
	scanf("%d", &n);
	while(n--)
	{
		LL a, t;
		scanf("%lld%lld", &a, &t);
		if(t == 1) l += a, r += a, add += a;
		else if(t == 2) l = max(l, a), r = max(r, a);
		else l = min(l, a), r = min(r, a);
	}
	scanf("%d", &q);
	while(q--)
	{
		LL x;
		scanf("%lld", &x);
		printf("%lld\n", clamp(x + add, l, r));
	}
	return 0;
}

标签:dots,10,le,AtCoder,int,题解,196,输出,100
From: https://www.cnblogs.com/stanleys/p/18403462/abc196

相关文章

  • Mynavi Programming Contest 2021 (AtCoder Beginner Contest 201) A~E 题解
    A-TinyArithmeticSequence题目大意给定序列\(A=(A_1,A_2,A_3)\)。能否将\(A\)重新排列,使得\(A_3-A_2=A_2-A_1\)?\(1\leA_i\le100\)输入格式\(A_1~A_2~A_3\)输出格式如果能将\(A\)重新排列使得\(A_3-A_2=A_2-A_1\),输出Yes;如果不能,输出No。样例\(A\)输出\((5......
  • AtCoder Beginner Contest 204 A~E 题解
    A-Rock-paper-scissors三个人玩石头剪刀布平局,其中两个出的分别是\(x,y\),求另一个人出的。\(0\lex,y\le2\)(\(0,1,2\)分别表示石头,剪刀,布)输入格式\(x,y\)输出格式用整数格式输出答案。样例\(x\)\(y\)输出\(0\)\(1\)\(2\)\(0\)\(0\)\(0\)分析石头......
  • AISing Programming Contest 2021 (AtCoder Beginner Contest 202) A~E 题解
    A-ThreeDice一个人抛了三个骰子,它们的顶面分别是\(a,b,c\)。求它们的底面之和。这里用的骰子是标准骰子,即两个相对的面之和为\(7\)。\(1\lea,b,c\le6\)输入格式\(a~b~c\)输出格式输出答案。样例\(a\)\(b\)\(c\)答案\(1\)\(4\)\(3\)\(13\)\(5\)\(6......
  • AtCoder Beginner Contest 203 (Sponsored by Panasonic) A~E 题解
    A-Chinchirorin题目大意给定三个整数\(a,b,c\),如果它们中有两个相等,输出另一个;否则,输出\(0\)。\(1\lea,b,c\le6\)输入格式\(a~b~c\)输出格式如果\(a,b,c\)中有两个相等,输出另一个;否则,输出\(0\)。样例\(a\)\(b\)\(c\)输出\(2\)\(5\)\(2\)\(5\)\(4\)......
  • AtCoder Beginner Contest 199 (Sponsored by Panasonic) A~E 题解
    A-SquareInequality题目大意给定三个整数\(A,B,C\)。判断\(A^2+B^2<C^2\)是否成立。\(0\leA,B,C\le1000\)输入格式\(A~B~C\)输出格式如果\(A^2+B^2<C^2\),输出Yes;否则,输出No。样例\(A\)\(B\)\(C\)输出\(2\)\(2\)\(4\)Yes\(10\)\(10\)\(10\)N......
  • KYOCERA Programming Contest 2021 (AtCoder Beginner Contest 200) A~E 题解
    A-Century题目大意公元\(N\)年在第几个世纪中?一个世纪是由\(100\)个年份组成的一个区间。如,\(1\)世纪为\([1,100]\)年,\(2\)世纪为\([101,200]\)年,……\(1\leN\le3000\)输入格式\(N\)输出格式将答案输出为一个整数。样例\(N\)输出\(2021\)\(21\)\(200......
  • AtCoder Beginner Contest 205 A~E 题解
    A-kcal题目大意我们有一种每\(100\)毫升含有\(A\)千卡热量的饮料。\(B\)毫升的这种饮料含有多少千卡热量?\(0\leA,B\le1000\)输入格式\(A~B\)输出格式输出\(B\)毫升这种饮料包含的的千卡数。最大允许浮点数精度误差\(10^{-6}\)。样例\(A\)\(B\)输出\(45\)......
  • AtCoder Beginner Contest 168 C~D 题解
    这次比赛的题名很特殊,是由符号+(+英文+)组成的......
  • AtCoder Beginner Contest 171 A~D 题解
    A-αlphabet题目大意输入一个英文字母\(a\),判断它是大写还是小写。输入格式\(a\)输出格式如果\(a\)为小写,输出a;如果\(a\)为大写,输出A。样例输入1B样例输出1AB为大写,所以输出A。样例输入2a样例输出2aa为小写,所以输出a。代码#include<cstdio>usingnames......
  • AtCoder Beginner Contest 187 A~D 题解
    A-LargeDigits题目大意给定两个三位整数\(A\)和\(B\),求它们数位和的最大值。数位和:例如,\(123\)的数位和是\(1+2+3=6\)。\(100\leA,B\le999\)输入格式\(A~~B\)输出格式一行,即\(A\)和\(B\)数位和的最大值。样例输入输出12323495939531710099927......