Codeforces Round #677 (Div. 3)
Powered by:AB_IN 局外人
(补一补陈年老番)
看大佬的答题实录真的受益匪浅qwq,以前总是觉得 p y py py更加方便,但其实 p y py py有的一些东西 C + + C++ C++也有,我还是太菜了。
A. Boring Apartments
模拟即可。
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)
B. Yet Another Bookshelf
求使原数列中任意两个
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))
C. Dominant Piranha
题意挺有意思的:任选一项,每次可以把消去比其小的相邻项,同时该项
+
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]<lst[i]) or (i<n-1 and lst[i+1]<lst[i])):
index=i+1
print(index)
D. Districts Connection
这个题我一开始理解错题意了,以为必须要首尾连成一个环。但其实不是,题意是要连成一个树,然后每条边的端点不一样就行了。
那这样的话,只有一种情况不成立,就是端点全是一样的。
如果不全是一样的,我们可以开始随便挑选一个端点
a
a
a,然后把不和
a
a
a一样的点和
a
a
a连起来,最后随意挑一个异于
a
a
a的点,吧剩余的
a
a
a连在它上。
#include <bits/stdc++.h>
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:求数组中某个元素的个数,这样的函数,大开眼界。
- 大佬手速可太快了。。
E. Two Round Dances
排列组合。
这里用到了一个知识点:循环排列(也称圆排列)
指从n个不同元素中取出m(1≤m≤n)个不同的元素排列成一个环形,既无头也无尾。两个循环排列相同当且仅当所取元素的个数相同并且元素取法一致,在环上的排列顺序一致。(百度百科)
这个圈旋转相同视为一种组合。
公式如下:
C n m × ( m − 1 ) ! C_{n}^{m} ×(m-1)! Cnm×(m−1)!
进而得出
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×(n−1)!
import math
n = 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/
完结。
相关文章
- Codeforces Round #327 (Div. 2) B. Rebranding C. Median Smoothing
- Codeforces Round #326 (Div. 2) B. Pasha and Phone C. Duff and Weight Lifting
- Codeforces Round #323 (Div. 2) C.GCD Table
- Codeforces Round #267 (Div. 2)
- Codeforces Round #256 (Div. 2) C. Painting Fence(分治贪心)
- Codeforces Round #265 (Div. 2) D. Restore Cube
- Codeforces Beta Round #75 (Div. 2)---A. Chips
- Codeforces Round #649 (Div. 2) A. XXXXX
- Codeforces Round #648 (Div. 2) E. Maximum Subsequence Value 贪心
- Codeforces Round #648 (Div. 2) F. Swaps Again
- Codeforces Round #669 (Div. 2)