首页 > 其他分享 >LINE Verda Programming Contest (AtCoder Beginner Contest 263) A~E 题解

LINE Verda Programming Contest (AtCoder Beginner Contest 263) A~E 题解

时间:2024-09-08 23:13:58浏览次数:9  
标签:输出 AtCoder le Contest int 题解 LL maxn text

A - Full House

题目大意

来自一个掼蛋爱好者的翻译qwq

给定一副扑克牌中五张牌的编号\(A,B,C,D,E\),判断这五张是否为一组“三带二”。(不懂的自行百度

数据范围:\(1\le A,B,C,D,E\le 13\),且\(A,B,C,D,E\)不会全部相同。

输入格式

\(A~B~C~D~E\)

输出格式

如果是“三带二”,输出Yes;否则,输出No

样例

\(A\) \(B\) \(C\) \(D\) \(E\) 输出
\(1\) \(2\) \(1\) \(2\) \(1\) Yes
\(12\) \(12\) \(11\) \(1\) \(2\) No

分析

嘿嘿,被自己的翻译给笑喷了吓住了,从来没见过这么垃圾的翻译!
话不多说,这A题就是水(虽然studentWheat这位大佬还WA了3次,具体怎么WA的请大家好好学学引以为戒),解法很多,但是个人感觉还是直接统计一下来得简单明了,见代码。

代码

#include <cstdio>
using namespace std;

int cnt[13];

int main()
{
	for(int i=0; i<5; i++)
	{
		int x;
		scanf("%d", &x);
		cnt[--x] ++;
	}
	bool has2 = false, has3 = false;
	for(int i=0; i<13; i++)
		if(cnt[i] == 2) has2 = true;
		else if(cnt[i] == 3) has3 = true;
	puts(has2 && has3? "Yes": "No");
	return 0;
}

B - Ancestor

题目大意

有\(N\)个人,第\(i\)个人的父/母是\(P_i\),题目保证\(P_i<i\)。
问:第\(N\)个人是第\(1\)个人的第几代?

\(2\le N\le 50\)
\(1\le P_i<i\)

输入格式

\(N\)
\(P_2~P_3~\dots~P_N\)

输出格式

输出答案。

分析

本题可以使用\(\text{DFS}\),但没有必要。题目限制条件特别给出了\(P_i<i\),因此如果按输入顺序依次处理每个人的世代,一个人的父亲肯定在这个人之前被考察到。

下面来看详细过程。
我们设\(\text{depth}_i=~\)第\(i\)个节点的深度,因此答案为\(\text{depth}_N\)。
初始时,\(\text{depth}_0=0\)。对于\(i=1\dots N\),依次设置\(\text{depth}_i:=\text{depth}_{P_i}+1\)。
最终,输出结果即可。总时间复杂度为\(\mathcal O(N)\)。

代码

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

int dep[maxn];

int main()
{
	int n;
	scanf("%d", &n);
	for(int i=1; i<n; i++)
	{
		int f;
		scanf("%d", &f);
		dep[i] = dep[--f] + 1;
	}
	printf("%d\n", dep[n - 1]);
	return 0;
}

C - Monotonically Increasing

题目大意

输出所有的长度为\(N\)的严格上升的序列,其中每个元素都在\([1,M]\)之间,按字典升序输出,\(1\le N\le M\le 10\)。

输入格式

\(N~M\)

输出格式

字典升序输出所有符合条件的序列,一行一个,序列中的每个元素用空格分隔。

分析

基础的回溯算法题,见代码。

代码

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

int n, m, ans[maxn];

void dfs(int pos, int last)
{
	if(pos == n)
	{
		for(int i=0; i<n; i++)
			printf("%d ", ans[i]);
		putchar('\n');
		return;
	}
	while(++last <= m)
	{
		ans[pos] = last;
		dfs(pos + 1, last);
	}
}

int main()
{
	scanf("%d%d", &n, &m);
	dfs(0, 0);
	return 0;
}

D - Left Right Operation

题目大意

给定长为\(N\)的整数序列\(A=(A_1,A_2,\dots,A_N)\)。
你可以进行下列两个操作,每个最多一次:

  • 选择整数\(x\),将\(A\)的前\(x\)项全部改成\(L\)。
  • 选择整数\(y\),将\(A\)的后\(y\)项全部改成\(R\)。

求操作后,最小的\(A\)中所有元素之和。

\(1\le N\le 2\times 10^5\)
\(-10^9\le L,R,A_i\le 10^9\)

输入格式

\(N~L~R\)
\(A_1~A_2~\dots~A_N\)

输出格式

输出答案。

分析

令\(f_i=(\)使用操作\(1\)选择\(x\le i\)时的前\(i\)个序列元素的最小和\()\),
\(~~~~g_i=(\)使用操作\(2\)选择\(y\le i\)时的后\(i\)个序列元素的最小和\()\),
则可得递推式\(f_i=\min\{f_{i-1}+A_i,L\times i\}\),\(g_i\)同理。
此时,枚举两种操作的分界点\(i\),则答案为\(\min\limits_{i=1}^N(f_i+g_{N-i})\)。实现时,可将\(g\)数组倒过来计算,这样答案为\(\min\limits_{i=1}^N(f_i+g_{i+1})\)。

递推式的正确性证明
前面已经提到了,\(f_i=\min\{f_{i-1}+A_i,L\times i\}\)。为什么?
先看\(\min\)后面的部分,应该好理解,就是前\(i\)个全部替换成\(L\)的总和。前面的\(f_{i-1}+A_i\)才是关键。考虑\(f_{i-1}\)的计算来源,要么是从\(f_{i-2}+A_{i-1}\)递推过来的,要么也是直接用\(L\times(i-1)\)得到的。再考虑\(f_{i-2},f_{i-3},\dots,f_1\)会发现,递推式的结果一定是(一段\(L\))+(一段\(A_i\))得到的。因此,这个递推式正确。\(g\)的正确性也可以用同样的方法证明,感兴趣的读者可以自行尝试。

总时间复杂度为\(\mathcal O(N)\)。

代码

注意使用long long

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

using LL = long long;
inline LL min(const LL& x, const LL& y)
{
	return x < y? x: y;
}

int a[maxn];
LL f[maxn], g[maxn];

int main()
{
	int n, l, r;
	scanf("%d%d%d", &n, &l, &r);
	for(int i=0; i<n; i++)
		scanf("%d", a + i);
	f[0] = min(l, a[0]);
	for(int i=1; i<n; i++)
		f[i] = min(f[i - 1] + a[i], (i + 1LL) * l);
	for(int i=n-1; i>=0; i--)
		g[i] = min(g[i + 1] + a[i], LL(n - i) * r);
	LL ans = g[0];
	for(int i=0; i<n; i++)
		ans = min(ans, f[i] + g[i + 1]);
	printf("%lld\n", ans);
	return 0;
}

E - Sugoroku 3

题目大意

有\(N\)个方格,分别是方格\(1\),方格\(2\),..,方格\(N\)。
在方格\(1,2,\dots,N-1\)上,各有一枚骰子。方格\(i\)上的骰子会按照相同的概率随机输出\(0,1,\dots,A_i\)中的一个。

直到到达方格\(N\)之前,你每次会前进骰子输出的步数。换句话说,如果你在方格\(x\)上(\(1\le x<N\)),骰子输出了数字\(y\)(\(0\le y\le A_i\)),你下一步会到达方格\(x+y\)。

求到达方格\(N\)步数的期望值,对\(998244353\)取模。

\(2\le N\le 2\times 10^5\)
\(1\le A_i\le N-i\)(\(1\le i<N\))

有理数取模洛谷模板:P2613
任意一个有理数都可被表示为\(\frac PQ\)的形式。令\(R\)为取模的结果,则\(R\times Q\equiv P~(\bmod~998244353)\)。
友情提示:对于除法计算,如\(\frac AB\)计算时,改为\(A\times B^{P-2}\bmod P\),其他逐步取模即可。本题中,\(P=998244353\)。

输入格式

\(N\)
\(A_1~A_2~\dots~A_{N-1}\)

输出格式

输出答案,对\(998244353\)取模。

分析

令\(\text{dp}_i=~\)从\(i\)到\(N\)的期望步数,则初始状态为\(\text{dp}_N=0\),答案为\(\text{dp}_1\)。
由于在方格上不能倒退,因此考虑倒序计算\(\text{dp}\)。对于第\(i\)个点,易得

\[\text{dp}_i=\frac{\sum\limits_{j=i}^{i+A_i}\text{dp}_j}{A_i+1}+1 \]

其中,求和即遍历后面每一个下一步可能到达的位置,乘上出现概率\(\frac1{A_i+1}\),最后再加上\(1\)表示使用一步。
由于左右都有\(\text{dp}_i\),无法直接计算,我们将其单独提出并解方程,得:

\[\text{dp}_i=\frac{(\sum\limits_{j=i}^{i+A_i}\text{dp}_j)+A_i+1}{A_i} \]

此时,时间复杂度为\(\mathcal O(N^2\log P)\)(快速幂inv操作需要\(\log P\)的时间,其中\(P=998244353\)),使用后缀和优化后可达\(\mathcal O(N\log P)\),可以通过本题。

代码

#include <cstdio>
#define maxn 200005
#define MOD 998244353
using namespace std;

using LL = long long;
int a[maxn], suf[maxn];

inline int inv(LL x)
{
	LL res = 1LL;
	int p = MOD - 2;
	while(p)
	{
		if(p & 1) (res *= x) %= MOD;
		(x *= x) %= MOD, p >>= 1;
	}
	return res;
}

int main()
{
	int n, cur;
	scanf("%d", &n);
	for(int i=0; i<n-1; i++)
		scanf("%d", a + i);
	for(int i=n-2; i>=0; i--)
	{
		int t = suf[i + 1] - suf[i + 1 + a[i]];
		if(t < 0) t += MOD;
		cur = (a[i] + t + 1LL) % MOD * inv(a[i]) % MOD;
		if((suf[i] = suf[i + 1] + cur) >= MOD)
			suf[i] -= MOD;
	}
	printf("%d\n", cur);
	return 0;
}

标签:输出,AtCoder,le,Contest,int,题解,LL,maxn,text
From: https://www.cnblogs.com/stanleys/p/18403692/abc263

相关文章

  • BZOJ 1396 识别子串 题解
    Statement给\(S\),令\(x\)为\(S\)的第\(k\)个字符,称\(T=S[i..j]\)为关于\(x\)的识别子串,当且仅当:\(i\lek\lej\)(含\(x\)这一位)\(T\)在\(S\)中只出现一次求\(S\)关于每一位字符的最短识别子串长度,\(|S|\le10^5\).Solution1以下是我没看题解瞎胡的首先......
  • 动态规划01背包的一个例题——洛谷P2871 题解
    题面有N件物品和一个容量为M的背包。第I件物品的重量是W[i],价值是D[i].求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。样例数据输入46142631227输出23分析(如果亲爱的读者对动态规划略有了解的话应该能看出来这是个01背包的板子......
  • BZOJ 3796 Mushroom追妹纸 题解
    Statement给\(s_1,s_2,s_3\),求最长的\(w\)的长度,满足\(w\)是\(s_1\)子串\(w\)是\(s_2\)子串\(s_3\)不是\(w\)子串Solution1以下是我没看题解瞎胡的首先一个弱智想法是,枚举\(s_1\)上\(w\)的左端点,二分右端点,判定时\(s_2\)用SAM,\(s_3\)用单串AC自动......
  • BZOJ 4502 串 题解
    妙妙数数题key:数数题通常是,对于特定形式的计数,就盯着这个模式观察,看出一些充要条件、计数形式的转化,然后想办法维护。优化的本质就是把难算的变成好算的,把不好一起统计的(只能一个个数的)以某种角度、用某些数据结构,一起统计(多个多个数)。我觉得难点通常在于“盯出一些充要条件”,......
  • 题解:AT_arc116_b [ARC116B] Products of Min-Max
    在题库里面乱翻,就翻到了。因为在这道题里面子序列不需要考虑元素顺序,所以原序列无论是什么顺序都不会影响答案。所以先把元素按照从大到小的顺序排列,然后考虑每个元素的贡献。在当前序列中,对于元素\(a_i\),不妨设其为最小值,并去寻找它能作为哪些序列的最小值。容易发现它作为最......
  • 题解:AT_abc369_c [ABC369C] Count Arithmetic Subarrays
    很水的一道题,但是硬控我半个小时呜呜呜。它问等差数列的数量,我们发现只要找到所有的等差数列,那么答案一定包含在这些数列的连续子序列中。求所有等差数列显然可以线性,我们求出每个等差数列的长度\(n\),那么连续子序列个数即为\(n(n+1)\over2\)。至于求的话我定义了两个指针,每......
  • AtCoder Beginner Contest 253 A~E 题解
    A-Median?题目大意给定正整数\(a,b,c\),判断\(b\)是否为三个数中的中位数(即从小到大排序后是第二个,不是平均数)。\(1\lea,b,c\le100\)输入格式\(a~b~c\)输出格式如果\(b\)是三个数中的中位数,输出Yes;否则,输出No。样例\(a\)\(b\)\(c\)输出\(5\)\(3\)\(2\)Y......
  • AtCoder Beginner Contest 241 (Sponsored by Panasonic) D~F 题解
    D-SequenceQuery题目大意我们有一个空序列\(A\)。请依次处理\(Q\)个命令,每个命令有三种类型,每种类型的格式如下:1x:将\(x\)加入\(A\)(不去重)2xk:求在\(A\)的\(\lex\)的元素中,第\(k\)大的值。3xk:求在\(A\)的\(\gex\)的元素中,第\(k\)小的值。\(1\leQ\le2\times10^5......
  • AtCoder Beginner Contest 242 C~E 题解
    C-1111galpassword题目大意给定正整数\(N\),求符合下列条件的整数\(X\)的个数,对\(998244353\)取模:\(X\)是\(N\)位的正整数\(X\)的每一位数都在\([1,9]\)之间(0不行);\(X\)的相邻两位数之差的绝对值不超过\(1\)。\(2\leN\le10^6\)输入格式\(N\)输出格式输出答案。样......
  • AtCoder Beginner Contest 245 A~E 题解
    A-Goodmorning题目大意在同一天里,Takahashi在\(A\)时\(B\)分起床,Aoki在\(C\)时\(D\)分\(1\)秒起床,请问谁起床更早?\(0\leA,C<24\)\(0\leB,D<60\)输入格式\(A~B~C~D\)输出格式输出起得更早的人的名字(Takahashi或Aoki)。样例\(A\)\(B\)\(C\)\(D\)输出\(7\)......