1. 程式人生 > >老年OIer的Python實踐記—— Codeforces Round #555 (Div. 3) solution

老年OIer的Python實踐記—— Codeforces Round #555 (Div. 3) solution

columns incr balanced stdio.h 決策 ont days long long 出現次數

對沒錯下面的代買全部是python 3(除了E的那個multiset)

題目鏈接:https://codeforces.com/contest/1157

A. Reachable Numbers

按位算貢獻,一位數的貢獻直接算即可

n=int(input())
ans=0
while (n>=10):
    tmp=n%10
    tmp=10-tmp
    ans+=tmp
    n+=tmp
    while (n>0) and (n%10==0):
        n//=10
ans+=9
print(ans)

B. Long Number

貪心,肯定是優先變最高位

import sys
import os

n=int(input())
a=input()
f=list(map(int,input().split()))
#print(f)
ans=""
pos=0
while (pos<n):
    now=ord(a[pos])-48
    if (a[pos]>=chr(f[now-1]+48)):
        ans=ans+a[pos]
        pos+=1
    else:
        while (pos<n) and (a[pos]<=chr(f[now-1]+48)):
            ans=ans+chr(f[now-1]+48)
            pos+=1
            if (pos<n) :
                now=ord(a[pos])-48
        print(pos)
        for i in range (pos,n):
            ans=ans+a[i]
        pos=n
        break
print(ans)

C1&C2 Increasing Subsequence

建立兩個指針\(l\)\(r\),同時記錄上一次的答案,暴力掃描即可

註意\(a_l==a_r\)時很明顯決策是只會從一端開始取數,直接做完

n=int(input())
ans=[]
a=list(map(int,input().split()))
l=-0
r=n-1
now=0
while l<=r:
    #print(l,r,now,a[l],a[r])
    if a[l]<a[r] and a[l]>now:
        now=a[l]
        l+=1
        ans.append('L')
    elif a[r]<a[l] and a[r]>now:
        now=a[r]
        r-=1
        ans.append('R')
    elif a[r]<a[l] and a[l]>now:
        now=a[l]
        l+=1
        ans.append('L')
    elif a[l]<a[r] and a[r]>now:
        now=a[r]
        r-=1
        ans.append('R')
    elif a[l]==a[r]:
        #print(l,r,now)
        if a[l]<=now:
            break
        nowl=now
        nowr=now
        pos=l
        cnt1=0
        cnt2=0
        while pos<=r and a[pos]>nowl:
            nowl=a[pos]
            pos+=1
            cnt1+=1
        pos=r
        while l<=pos and a[pos]>nowr:
            nowr=a[pos]
            pos-=1
            cnt2+=1
        if (cnt1>cnt2):
            for i in range(0,cnt1):
                ans.append('L')
        else:
            for i in range(0,cnt2):
                ans.append('R')
        break
    else:
        break
print(len(ans))
for i in ans:
    print(i,end="")

D.N Problems During K Days

人民群眾喜聞樂見的構造題

先把這個序列設定為\([x,x+1,\cdots,x+k-1]\)之後再進行調整

對於每一個位置\(i\)考慮在\([i,n]\)中所有的數都加上某個相同的數,這個可以直接得到,同時要和\(a_{i-1}*2-a_i\)\(min\)

最後看\(n\)是否還有剩余

import sys

n,k=map(int,input().split())
a=[0]*(k+2)
if k*(k+1)>n*2:
    print("NO")
    sys.exit()
for i in range(1,k+1):
    a[i]=i
n-=k*(k+1)//2
rest=n//k
n-=rest*k
a[1]+=rest
for i in range(2,k+1):
    a[i]=a[i-1]+1
    rest=n//(k-i+1)
    tmp=min(rest,a[i-1]*2-a[i])
    a[i]+=tmp
    n-=(k-i+1)*tmp
if n>0:
    print("NO")
    sys.exit()
print("YES")
for i in range(1,k+1):
    print(a[i],end=" ")

E. Minimum Array

簡單題

對於\(a_i\),你期望找到一個\(b_i\),使得\(a_i+b_i=n\),如果找不到,那你就希望找一個大於\(b_i\)的又和\(b_i\)最接近的

這不是lower_bound這是什麽

\(b\)丟到multiset中,每次對\(a_i\)lower_bound一下

當然萬一找不到的話還是要找最小的\(b_i\),比較一下即可

使用c++實現

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x)&(-x)
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,a,b) for (int i=a;i>=b;i--)
#define maxd 1000000007
typedef long long ll;
const int N=100000;
const double pi=acos(-1.0);
int n,a[200200],b[200200];
multiset<int> s;

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

int main()
{
    n=read();
    rep(i,1,n) a[i]=read();
    rep(i,1,n) {b[i]=read();s.insert(b[i]);}
    multiset<int>::iterator it;
    rep(i,1,n)
    {
        int tmp=(n-a[i])%n;
        it=s.lower_bound(tmp);
        if (it==s.end()) it--;
        int st=*(s.begin()),now=*it;
        if ((now+a[i])%n>(st+a[i])%n) now=st;
        s.erase(s.lower_bound(now));
        printf("%d ",(now+a[i])%n);
    }
    return 0;
}

F. Maximum Balanced Circle

又是構造題

首先你選的數一定是在某一個連續區間內的數,這樣你就解決了\(|a_i-a_{i+1}|\leq 1\)

然後就是\(|a_1-a_k|\leq 1\),你可以把所有的\(a_i\)排成一個先遞增後遞減的形式(就像山峰一樣)

然後出現次數為1的數要麽出現在山腳(\(a_1\)),要麽出現在山頂(\(max\{a_i\}\)

然後就做完啦

n=int(input())
a=list(map(int,input().split()))
cnt=[0]*(200005)
for i in range(0,n):
    cnt[a[i]]+=1
ans=0
ansl=0
ansr=0
l=1
N=200001
while (l<=N):
    if cnt[l]==0:
        l+=1
    else:
        r=l
        now=0
        while (r<=N):
            if cnt[r]==0:
                r-=1
                break
            elif cnt[r]==1 and l!=r:
                now+=cnt[r]
                break
            else:
                now+=cnt[r]
                r+=1
        if now>ans:
            ansl=l
            ansr=r
            ans=now
        #print(l,r,now)
        if l==r:
            l=r+1
        else:
            l=r
seq=[]
for i in range(ansl,ansr+1):
    seq.append(i)
    cnt[i]-=1
for i in range(ansr,ansl-1,-1):
    while cnt[i]>0:
        seq.append(i)
        cnt[i]-=1
print(len(seq))
for i in seq:
    print(i,end=" ")

G. Inverse of Rows and Columns

對沒錯還是構造題

考慮一個合法方案一定至少符合下列兩個條件之一:

1)第一行全部為\(0\) 2)最後一行全部為\(1\)

我們枚舉當前滿足哪一個條件,那麽根據當前行中每一個數的情況我們就確定了當前列的翻轉情況

接下來我們枚舉行,找到中間的斷點(由0變成1的地方),以此確定行的反轉情況

最後暴力取出所有書\(check\)即可

import sys
n=0
m=0
sq=[[0]*(310)]*(310)
ansx=[]
ansy=[]
tmp=[[0]*(310)]*(310)

def chk():
    val=[]
    for i in range(0,n):
        for j in range(0,m):
            val.append(tmp[i][j])
    Len=len(val)
    for i in range(1,Len):
        if val[i-1]>val[i]:
            return False
    return True

n,m=map(int,input().split())
for i in range(0,n):
    sq[i]=list(map(int,input().split()))
for i in range(0,n):
        tmp[i]=list(sq[i])
for i in range(0,m):
    if tmp[0][i]==1:
        ansy.append(1)
        for j in range (0,n):
            tmp[j][i]=1-tmp[j][i]
    else:
        ansy.append(0)
op=0
for i in range(0,n):
    flag0=0
    flag1=0
    for j in range(0,m):
        if tmp[i][j]==0:
            flag0=1
        else:
            flag1=1
    if flag0==1 and flag1==1:
        op=1
        if tmp[i][0]==1:
            ansx.append(1)
            for j in range (0,m):
                tmp[i][j]=1-tmp[i][j]
        else:
            ansx.append(0)
    elif flag0==1:
        if op==0:
            ansx.append(0)
        elif op==1:
            ansx.append(1)
            for j in range(0,m):
                tmp[i][j]=1-tmp[i][j]
    elif flag1==1:
        if op==0:
            ansx.append(1)
            for j in range(0,m):
                tmp[i][j]=1-tmp[i][j]
        else:
            ansx.append(0)
if chk():
    print("YES")
    for i in range(0,n):
        print(ansx[i],end="")
    print()
    for i in range(0,m):
        print(ansy[i],end="")
    sys.exit()

for i in range(0,n):
    tmp[i]=list(sq[i])
ansx=[]
ansy=[]
for i in range(0,m):
    if (tmp[n-1][i]==1):
        ansy.append(0)
    else:
        ansy.append(1)
        for j in range(0,n):
            tmp[j][i]=1-tmp[j][i]

op=0
for i in range(0,n):
    flag0=0
    flag1=0
    for j in range(0,m):
        if tmp[i][j]==1:
            flag1=1
        else:
            flag0=1
    if flag1==1 and flag0==1:
        op=1
        if tmp[i][0]==1:
            ansx.append(1)
            for j in range(0,m):
                tmp[i][j]=1-tmp[i][j]
        else:
            ansx.append(0)
    elif flag0==1:
        if op==0:
            ansx.append(0)
        else:
            ansx.append(1)
            for j in range(0,m):
                tmp[i][j]=1-tmp[i][j]
    elif flag1==1:
        if op==1:
            ansx.append(0)
        else:
            ansx.append(1)
            for j in range(0,m):
                tmp[i][j]=1-tmp[i][j]
if chk():
    print("YES")
    for i in range(0,n):
        print(ansx[i],end="")
    print()
    for i in range(0,m):
        print(ansy[i],end="")
    sys.exit()
print("NO")

老年OIer的Python實踐記—— Codeforces Round #555 (Div. 3) solution