Codeforces Round #677 (Div. 3)
发布日期:2021-05-07 23:18:52 浏览次数:21 分类:精选文章

本文共 3395 字,大约阅读时间需要 11 分钟。

Powered by:AB_IN 局外人

(补一补陈年老番)

看大佬的答题实录真的受益匪浅qwq,以前总是觉得 p y py py更加方便,但其实 p y py py有的一些东西 C + + C++ C++也有,我还是太菜了。

模拟即可。

for _ in range(int(input())):    s=input()    ans=0    if len(s)==1:      ans+=1    elif len(s)==2:      ans+=3    elif len(s)==3:      ans+=6    else:      ans+=10    ans+=(int(s[0])-1)*10    print(ans)

求使原数列中任意两个 1 1 1 之间不存在 0 0 0的最小操作数。

其实问题就转换为了,两个最远的 1 1 1之间 0 0 0的个数。

for _ in range(int(input())):  n=int(input())  lst=list(map(int,input().split()))  for i in range(n):    if lst[i]==1:      index1=i      break  for i in range(n-1,-1,-1):    if lst[i]==1:      index2=i      break  if index1==index2:    print(0)  else:    print(lst[index1:index2].count(0))

题意挺有意思的:任选一项,每次可以把消去比其小的相邻项,同时该项 + 1 +1 +1,问能否找到某项,使得若干次操作后数列只剩一项。

如果能,输出任一可行的最初找的项的下标,否则输出 − 1 -1 1

所以找的数越大越好,就输出这个数的下标就行了。但是如果遇到这种情况:

3   3   2   3   3 3 \ 3 \ 2 \ 3 \ 3 3 3 2 3 3
就不是哪个 3 3 3都可以了。所以在这个数是最大值的前提下,还得保证他的周围有比他小的数。

for _ in range(int(input())):  n=int(input())  lst=list(map(int,input().split()))  index=-1  ans=max(lst)  for i in range(n):    if lst[i]==ans and ((i>0 and lst[i-1]

这个题我一开始理解错题意了,以为必须要首尾连成一个环。但其实不是,题意是要连成一个树,然后每条边的端点不一样就行了。

那这样的话,只有一种情况不成立,就是端点全是一样的。

如果不全是一样的,我们可以开始随便挑选一个端点 a a a,然后把不和 a a a一样的点和 a a a连起来,最后随意挑一个异于 a a a的点,吧剩余的 a a a连在它上。

#include 
using namespace std;const int N = 1e5;int a[N];int t;void solve(){ int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); if(count(a + 1, a + 1 + n, a[1]) == n){ puts("No"); return; } else{ puts("Yes"); int las = 0; for(int i = 1; i <= n; i++){ if(a[i] != a[1]){ printf("1 %d\n", i); las = i; } } for(int i = 2; i <= n; i++){ if(a[i] == a[1]){ printf("%d %d\n", i, las); } } }}int main(){ scanf("%d", &t); while(t--){ solve(); } return 0;}

P S : PS: PS:

  • 多组数据的话,写 s o l v e ( ) solve() solve()函数,结束直接 r e t u r n return return,好处颇多!
  • 见识到了像 m a x _ e l e m e n t max\_element max_element:求最大值; c o u n t count count:求数组中某个元素的个数,这样的函数,大开眼界。
  • 大佬手速可太快了。。

排列组合。

这里用到了一个知识点:循环排列(也称圆排列)

指从n个不同元素中取出m(1≤m≤n)个不同的元素排列成一个环形,既无头也无尾。两个循环排列相同当且仅当所取元素的个数相同并且元素取法一致,在环上的排列顺序一致。(百度百科)

这个圈旋转相同视为一种组合。

公式如下:

C n m × ( m − 1 ) ! C_{n}^{m} ×(m-1)! Cnm×(m1)!

进而得出

A n m m \frac {A _{n} ^{m}} { m} mAnm

那么这个题就迎刃而解了,题意是从 n n n个人中分成各 n 2 \frac {n} {2} 2n 人的两堆,先选出 n 2 \frac {n} {2} 2n人放在左圈(其余 n 2 \frac {n} {2} 2n人自然放在右圈)。

先看左圈,相当于从 n n n个人中选出 n 2 {n} \over {2} 2n个人组成一个圈:

C n n 2 × A n 2 n 2 n 2 \frac {C_{n}^{

{n} \over {2}} × A _{
{n} \over {2}} ^{
{n} \over {2}}} {
{n} \over {2}} 2nCn2n×A2n2n

再看右圈,相当于从 n 2 {n} \over {2} 2n个人中选出 n 2 {n} \over {2} 2n个人组成一个圈:

C n 2 n 2 × A n 2 n 2 n 2 \frac {C_{
{n} \over {2}}^{
{n} \over {2}} × A _{
{n} \over {2}} ^{
{n} \over {2}}} {
{n} \over {2}}
2nC2n2n×A2n2n
最后由于两个圈是等价的,所以最后结果除以 2 2 2

结果就是

C n n 2 × A n 2 n 2 n 2 × C n 2 n 2 × A n 2 n 2 n 2 2 \frac {C_{n}^{

{n} \over {2}} × A _{
{n} \over {2}} ^{
{n} \over {2}}} {
{n} \over {2}} × \frac {C_{
{n} \over {2}}^{
{n} \over {2}} × A _{
{n} \over {2}} ^{
{n} \over {2}}} {
{n} \over {2}} \over{2} 22nCn2n×A2n2n×2nC2n2n×A2n2n

化简得到:

2 × ( n − 1 ) ! n {2×(n-1)!} \over {n} n2×(n1)!

import mathn = int(input())print( 2 * math.factorial(n-1) // n )

最后推荐一个查询数列的网站: h t t p : / / o e i s . o r g / http://oeis.org/ http://oeis.org/

完结。

上一篇:数论——唯一分解定理
下一篇:Py3 三种排序

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年04月09日 23时46分51秒