来自一个掼蛋爱好者的翻译qwq
给定一副扑克牌中五张牌的编号,判断这五张是否为一组“三带二”。(不懂的自行百度
数据范围:,且不会全部相同。
如果是“三带二”,输出Yes
;否则,输出No
。
输出 | |||||
---|---|---|---|---|---|
Yes |
|||||
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;
}
有个人,第个人的父/母是,题目保证。
问:第个人是第个人的第几代?
输出答案。
本题可以使用,但没有必要。题目限制条件特别给出了,因此如果按输入顺序依次处理每个人的世代,一个人的父亲肯定在这个人之前被考察到。
下面来看详细过程。
我们设第个节点的深度,因此答案为。
初始时,。对于,依次设置。
最终,输出结果即可。总时间复杂度为。
#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;
}
输出所有的长度为的严格上升的序列,其中每个元素都在之间,按字典升序输出,。
按字典升序输出所有符合条件的序列,一行一个,序列中的每个元素用空格分隔。
基础的回溯算法题,见代码。
#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;
}
给定长为的整数序列。
你可以进行下列两个操作,每个最多一次:
求操作后,最小的中所有元素之和。
输出答案。
令使用操作选择时的前个序列元素的最小和,
使用操作选择时的后个序列元素的最小和,
则可得递推式,同理。
此时,枚举两种操作的分界点,则答案为。实现时,可将数组倒过来计算,这样答案为。
递推式的正确性证明
前面已经提到了,。为什么?
先看后面的部分,应该好理解,就是前个全部替换成的总和。前面的才是关键。考虑的计算来源,要么是从递推过来的,要么也是直接用得到的。再考虑会发现,递推式的结果一定是(一段)+(一段)得到的。因此,这个递推式正确。的正确性也可以用同样的方法证明,感兴趣的读者可以自行尝试。
总时间复杂度为。
注意使用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;
}
有个方格,分别是方格,方格,..,方格。
在方格上,各有一枚骰子。方格上的骰子会按照相同的概率随机输出中的一个。
直到到达方格之前,你每次会前进骰子输出的步数。换句话说,如果你在方格上(),骰子输出了数字(),你下一步会到达方格。
求到达方格步数的期望值,对取模。
()
有理数取模【洛谷模板:P2613】
任意一个有理数都可被表示为的形式。令为取模的结果,则。
友情提示:对于除法计算,如计算时,改为,其他逐步取模即可。本题中,。
输出答案,对取模。
令从到的期望步数,则初始状态为,答案为。
由于在方格上不能倒退,因此考虑倒序计算。对于第个点,易得
其中,求和即遍历后面每一个下一步可能到达的位置,乘上出现概率,最后再加上表示使用一步。
由于左右都有,无法直接计算,我们将其单独提出并解方程,得:
此时,时间复杂度为(快速幂inv
操作需要的时间,其中),使用后缀和优化后可达,可以通过本题。
#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;
}