首页 > 其他分享 >AtCoder Beginner Contest 242 C~E 题解

AtCoder Beginner Contest 242 C~E 题解

时间:2024-09-08 21:17:17浏览次数:10  
标签:AtCoder le 10 int 题解 scanf long -- 242

C - 1111gal password

题目大意

给定正整数\(N\),求符合下列条件的整数\(X\)的个数,对\(998244353\)取模:

  • \(X\)是\(N\)位的正整数
  • \(X\)的每一位数都在\([1,9]\)之间(0不行
  • \(X\)的相邻两位数之差的绝对值不超过\(1\)。

\(2\le N\le 10^6\)

输入格式

\(N\)

输出格式

输出答案。

样例

\(N\) 输出
\(4\) \(203\)
\(2\) \(25\)
\(1000000\) \(248860093\)

分析

根据乘法原理可得,符合条件的\(N\)位数最多有\(9^N\)个,显然不能暴力求解。
但是,由于每一位会被上一位所限制,所以我们很容易想到使用\(\text{DP}\)求解。
令\(f(i,j)=X\)的第\(i\)位上出现\(j\)的可能数,易得:

\[f(i,j)=\begin{cases} 1&(i=1)\\ f(i-1,1)+f(i-1,2)&(j=1)\\ f(i-1,8)+f(i-1,9)&(j=9)\\ f(i-1,j-1)+f(i-1,j)+f(i-1,j+1)&(i>1,2\le j\le8) \end{cases} \]

因此,直接输出\(\sum\limits_{i=1}^9f(n,i)\)即可。

代码

本代码运用了滚动表的优化,当然也可以直接开\(N\times9\)大小的数组,但这样会导致内存占用大,不建议使用。

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

inline void mod(int& x)
{
	if(x >= MOD) x -= MOD;
}

int dp[9], ldp[9];

int main()
{
	int n;
	scanf("%d", &n);
	for(int i=0; i<9; i++)
		dp[i] = 1;
	while(--n)
	{
		for(int i=0; i<9; i++)
			ldp[i] = dp[i];
		mod(dp[0] += dp[1]), mod(dp[8] += dp[7]);
		for(int i=1; i<8; i++)
			mod(dp[i] += ldp[i - 1]),
			mod(dp[i] += ldp[i + 1]);
	}
	int ans = 0;
	for(int i=0; i<9; i++)
		mod(ans += dp[i]);
	printf("%d\n", ans);
	return 0;
}

D - ABC Transform

题目大意

给定由ABC组成的字符串\(S\)。令\(S_0=S\),\(S_i=S_{i-1}\)将ABC分别替换为BCCAAB的新字符串。
回答\(Q\)个查询,第\(i\)个查询的问题如下:

  • 求\(S_{t_i}\)的第\(k_i\)个字母。

\(1\le |S|\le 10^5\)
\(1\le Q\le 10^5\)
\(1\le t_i\le 10^{18}\)
\(1\le k_i\le min(10^{18},S_{t_i}\)的长度\()\)

输入格式

\(S\)
\(Q\)
\(t_1~k_1\)
\(\vdots\)
\(t_Q~k_Q\)

样例

样例输入1

ABC
4
0 1
1 1
1 3
1 6

样例输出1

A
B
C
B
  • \(S_0=~\)ABC
  • \(S_1=~\)AABCB

样例输入2

CBBAACCCCC
5
57530144230160008 659279164847814847
29622990657296329 861239705300265164
509705228051901259 994708708957785197
176678501072691541 655134104344481648
827291290937314275 407121144297426665

样例输出2

A
A
C
A
A

注意小心整数溢出问题。

分析

令\(f(t,k)=(S_0\)为AAA..时\(S_t\)的第\(k\)个字母,其中ABC分别对应\(0,1,2\)且\(k\)从\(0\)开始\()\),则通过找规律可得:

\[f(t,k)=\begin{cases} 0 & (t=0)\\ g(0,t) & (k=0)\\ g(f(t-1,\lfloor\frac k2\rfloor),(k\bmod2)+1) & (t>0,k>0) \end{cases} \]

其中\(g(c,x)\)为字符\(c\)在A,B,C,A,...这个环中\(c\)后面的第\(x\)个字符,即\(g(c,x)=(c+x)\bmod3\)。
因此,我们只要求出\(x\)在\(S\)的哪个字符分解后的结果中,再计算\(f\)即可。
答案为\(\mathrm{ans}=g(f(t,(k-1)\bmod2^t),S_{\lfloor\frac {k-1}{2t}\rfloor})\)。

代码

以下两种示范代码均使用非递归形式,当然也可使用递归形式。

代码1(标准)

#include <cstdio>
using namespace std;

char s[100005];

int main()
{
	scanf("%s", s);
	int q;
	scanf("%d", &q);
	while(q--)
	{
		long long t, k;
		scanf("%lld%lld", &t, &k);
		k --;
		int x = s[t < 64? k >> t: 0] - 'A'; // 防止t太大导致RE
		while(t > 0 && k > 0)
		{
			x = (x + int(k & 1LL) + 1) % 3;
			k >>= 1LL, t --;
		}
		putchar((t + x) % 3 + 'A');
		putchar('\n');
	}
	return 0;
}

代码2(优化)

#include <cstdio>
using namespace std;

char s[100005];

int main()
{
	scanf("%s", s);
	int q;
	scanf("%d", &q);
	while(q--)
	{
		long long t, k;
		scanf("%lld%lld", &t, &k);
		k --;
		int c = 0;
		if(t < 64)
		{
			c = s[k >> t] - 'A';
			k &= (1LL << t) - 1LL;
		}
		else c = s[0] - 'A';
		for(c+=t%3; k>0; k&=k-1) c ++;
		putchar(c % 3 + 'A');
		putchar('\n');
	}
	return 0;
}

E - (∀x∀)

题目大意

对于\(T\)个测试点,分别解决下列问题:
给定整数\(N\)和字符串\(S\),求合法字符串\(X\)的个数,使其符合下列条件:

  • \(|X|=N\)
  • \(X\)由大写英文字母组成,是一个回文串
  • 按字典序,\(X\le S\)

\(1\le T\le 250000\)
\(1\le N\le 10^6\)
\(1\le \sum N\le 10^6\)
\(|S|=N\)且由大写英文字母组成。

分析

显然,通过\(X\)的前\(\lceil\frac N2\rceil\)个字符就可以确定唯一的\(X\)。下面,我们以ABCDE为例:

  • ABCDE的前\(\lceil\frac N2\rceil\)个字符分别为ABC
  • 字典序小于ABC的字符串有\(28\)个(可看作一个\(26\)进制数来计算)
  • 判断ABCBA是否可行,与ABCDE比较
  • 可行,答案增加\(1\)得到\(29\)

因此,我们输出\(29\)。其他情况类似。

代码

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

using LL = long long;
char s[maxn];

int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		int n;
		scanf("%d%s", &n, s);
		long long x = 0LL;
		int j = n - 1 >> 1;
		for(int i=0; i<=j; i++)
			(x = x * 26LL + s[i] - 'A') %= MOD;
		bool ok = true;
		while(j >= 0)
		{
			if(s[j] < s[n - 1 - j]) break;
			if(s[j] > s[n - 1 - j]) { ok = false; break;}
			j --;
		}
		if(ok && ++x == MOD) x -= MOD;
		printf("%lld\n", x);
	}
	return 0;
}

标签:AtCoder,le,10,int,题解,scanf,long,--,242
From: https://www.cnblogs.com/stanleys/p/18403484/abc242

相关文章

  • 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\)......
  • AtCoder Beginner Contest 244 D~F 题解
    D-SwapHats题目大意有\(3\)个Takahashi,他们帽子的颜色分别为\(S_1,S_2,S_3\)。我们现在想通过正好\(10^{18}\)次操作,使得\(S_i=T_i\)。每次操作如下:选择\((i,j)\),交换\(S_i\)和\(S_j\)。试问能否达成目标?输入格式\(S_1~S_2~S_3\)\(T_1~T_2~T_3\)输出格式如果能达......
  • ARC138 B - 01 Generation 题解
    ARC138B-01Generation思路考虑逆向思维,很容易想到可以优先从后面删掉0(操作B的逆向操作),然后如果前面是0则删掉它并将序列翻转(操作A的逆向操作),一直重复这两个步骤直到字符串为空。如果中途无法操作,输出No,否则输出Yes。下面我们来证明这个方法的正确性:首先,假设有一个序列\(A......
  • AtCoder题解集锦
    注:本文原发表于CSDN,现已停止更新。原文如下:AtCoder题解集锦自己从全网整理的一些优质AtCoder题解,目前只有ABC(AtCoderBeginnerContest)的C~F。不定期更新。如您有更多需求,欢迎私信我或在评论区留言!\(\rarr\)题解列表传送门用法表格查找找到对应比赛的行找到对应......
  • AtCoder Beginner Contest 250 C~E 题解
    C-AdjacentSwaps题目大意\(N\)个球从左到右排成一列。开始时,从左往右的第\(i\)个球上写着数字\(i\)。请执行\(Q\)个操作,第\(i\)个操作如下:令\(j=~N\)个球中写着数字\(x_i\)的球的位置如果\(j=N\),将其与第\(j-1\)个球交换;否则,与第\(j+1\)个球交换。求所有操作后的球上分......
  • UNIQUE VISION Programming Contest 2022(AtCoder Beginner Contest 248)C~D 题解
    C-DiceSum题目大意有多少个整数序列\(A=(A_1,\dots,A_N)\)符合如下条件:\(1\leA_i\leM\)\(\sum\limits_{i=1}^NA_i\leK\)输出答案,对\(998244353\)取模。\(1\leN,M\le50\)\(N\leK\leNM\)输入格式\(N~M~K\)输出格式输出答案,对\(998244353\)取模。分析艹C题......
  • AtCoder Beginner Contest 252 A~G 题解
    前言这是我第一次写7题(A~G)的ABC题解,若有写得不好或者不到位的地方请多多指教,我将万分感激,感谢大家的支持!A-ASCIIcode题目大意给定正整数\(N\),输出ASCII码是\(N\)的字母。\(97\leN\le122\)输入格式\(N\)输出格式输出ASCII码是\(N\)的字母。分析注意a对应\(97\)......
  • AtCoder Beginner Contest 192 A~D 题解
    A-Star题目大意下一个大于\(X\)的\(100\)的倍数与\(X\)的差是多少?\(1\leX\le10^5\)输入格式\(X\)输出格式输出答案。样例\(X\)输出\(140\)\(60\)\(1000\)\(100\)分析下一个大于\(X\)的\(100\)的倍数是\((\lfloorX/100\rfloor+1)\times100\)。所......
  • AtCoder Beginner Contest 191 A~D 题解
    A-VanishingPitch题目大意一个球的速度是\(V~\text{m/s}\),它飞了\(T\)秒后会隐形,飞了\(S\)秒时会接触隐形。球在飞了\(D\)米后,人能看见它吗?输出Yes或者No。\(1\leV\le1000\)\(1\leT<S\le1000\)\(1\leD\le1000\)输入格式\(V~T~S~D\)输出格式输出答案。样例......
  • AtCoder Beginner Contest 190 A~D 题解
    A-VeryVeryPrimitiveGame题目大意Takahashi和Aoki在玩一个游戏。游戏规则是这样的:最开始,Takahashi和Aoki分别有\(A\)和\(B\)颗糖。他们将轮流吃一颗糖,第一个无法吃糖的人算输。如果\(C=0\),那么Takahashi先吃;如果\(C=1\),那么Aoki先吃。请输出最终胜者的名字。\(0\le......