Codeforces Global Round 4

心得体会:写这一场,让我发现了一个事情,py跑1e6的数据基本上就炸了,还是求稳C++好一些。但是还是想练一下py然后选择了py写。

A - Prime Minister

题目大意:给定一个n个数字的数组,要求你找出一种选取方法,使得选出来的数字里,没有超过a[1]一半的数字,并且要求选出来的数字总和大于等于n个数字之和的一半。

分析:简单的模拟,模出来看看合不合理就行了。

代码:

k = eval(input())
a = input().split()
for i in range(k):
    a[i] = int(a[i])
tot = 0
for i in range(k):
    tot += a[i]
if k == 2:
    if a[0] > a[1]:
        print('1\n1')
    else:
        print(0)
else:
    can = a[0]
    party = []
    party.append(1)
    for i in range(k):
        if a[0] >= a[i] * 2 and len(party) < k -1:
            can += a[i]
            party.append(i+1)
    if can * 2 > tot:
        print(len(party))
        for i in party:
            print(i, end = " ")
    else:
        print(0)

B - WOW Factor

题目大意:故意把w写成紧挨的两个vv,问你有多少个wow子序列。

分析:O(n)跑出每个字母o两端的紧挨的vv的个数,然后左边乘以右边的相加即可。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
typedef long long ll;
char s[maxn];
int l[maxn],r[maxn];
int main(){
    cin>>s;
    int n=strlen(s);
    ll tot = 0;
    l[0] = 0;
    for(int i=1;i<n;i++){
        if(s[i-1]=='v'&&s[i]=='v')
            tot ++;
        l[i] = tot;
    }
    r[n-1] = 0;
    tot = 0;
    for(int i=n-1;i>=1;i--) {
        if (s[i] == 'v' && s[i - 1] == 'v')
            tot++;
        r[i - 1] = tot;
    }
    ll ans = 0;
    for(int i=0;i<n;i++){
        if(s[i]=='o')
            ans += (ll)l[i] * r[i];
    }
    cout<<ans<<endl;
    return 0;
}

C - Tiles

题目大意:给定N x M大的区域,让你用1 X 1的方块去填,每个方块是由一个黑色三角形和一个白色三角形拼接起来的,并且要求相邻的两个方块的相邻线处的颜色不能相同,问你有多少种合适的放置方式,注意mod = 998244353。

分析:猜了个结论,1<<(n + m),还真的猜对了,直接秒过。

代码:

mod = 998244353
 
 
def quick_pow(a, b):
    res = 1
    while b > 0:
        if b & 1:
            res = res * a % mod
        a = a * a % mod
        b >>= 1
    return res
 
 
n, m = input().split()
n = int(n)
m = int(m)
print(quick_pow(2, n + m))

D - Prime Graph

题目大意:给定顶点的个数,让你构造出一张无向图,使得每个顶点的度数为素数,并且图的边数也为素数。

分析:先依次把每个点连上,使得每个顶点的度数都为2即可。然后连圈内的边,一直到边的条数为素数即可。

代码:

prime = []
maxn = 100000
G = []
 
def init():
    for i in range(1007):
        G.append([])
        for j in range(1007):
            G[i].append(0)
 
 
def sieve():
    for i in range(maxn):
        prime.append(1)
    prime[0] = prime[1] = 0
    for i in range(maxn):
        if prime[i]:
            j = 2 * i
            while j < maxn:
                prime[j] = 0
                j += i
 
 
init()
sieve()
n = eval(input())
tot = 0
for i in range(1, n):
    G[i][i+1] = 1
    tot += 1
G[1][n] = 1
tot += 1
j = n - 1
i = 1
while j > i:
    if prime[tot]:
        break
    G[i][j] = 1
    tot += 1
    i += 1
    j -= 1
 
print(tot)
for i in range(1, n + 1):
    for j in range(1, n + 1):
        if G[i][j]:
            print(str(i)+' '+str(j))

E - Archaeology

题目大意:给定一个字符串,让你找出一个长度不小于原字符串一半的回文子序列。

分析:直接模拟就行了,只用比较三个位置,s[l]和s[r],s[l - 1]和s[r],s[l]和s[r - 1]。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
char s[maxn];
bool vis[maxn];
int main() {
    cin >> s;
    int n = strlen(s);
    int l = 0, r = n - 1, cnt = 0;
    while (l <= r) {
        if (s[l] == s[r]) {
            vis[l] = vis[r] = true;
            if (l == r)
                cnt += 1;
            else
                cnt += 2;
            l += 1;
            r -= 1;
        } else if (s[l + 1] == s[r]) {
            vis[l + 1] = vis[r] = true;
            if (l + 1 == r)
                cnt += 1;
            else
                cnt += 2;
            l += 2;
            r -= 1;
        } else if (s[l] == s[r - 1]) {
            vis[l] = vis[r - 1] = true;
            if (l == r - 1)
                cnt += 1;
            else
                cnt += 2;
            l += 1;
            r -= 2;
        } else {
            r -= 1;
            l += 1;
        }
    }
    for (int i = 0; i < n; i++)
        if (vis[i])
            printf("%c", s[i]);
    return 0;
}
posted @ 2020-01-08 16:29  SwiftAC  阅读(141)  评论(0编辑  收藏  举报