Codeforces Runde # 678 (Div. 2) A, B, C, D, E.

A. Nachbestellung

Beurteilen Sie einfach, ob die Summe aller Elemente gleich m ist.

#include <bits/stdc++.h>
using namespace std;
int T;
int n,m;
int sum;
int main()
{
    
    
    scanf("%d",&T);
    while(T--)
    {
    
    
        scanf("%d%d",&n,&m);
        int x;
        sum=0;
        while(n--)
        {
    
    
            scanf("%d",&x);
            sum+=x;
        }
        if(sum==m)
        puts("YES");
        else
        puts("NO");
    }
    return 0;
}

B. Prime Square

Wenn n sehr klein ist, mach es einfach, ich direkt +4, +6, +8 ... um dies zu tun, kannst du auch 0, 1 wie die Antwort verwenden (ich dachte, du könntest 0QAQ während des Spiels nicht verwenden)

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
long long su[maxn],cnt;
bool isprime[maxn];
int a[maxn];
void prime()
{
    
    
    cnt=1;
    memset(isprime,1,sizeof(isprime));//初始化认为所有数都是素数
    isprime[0]=isprime[1]=0;//0和1不是素数
    for(long long i=2;i<=maxn;i++)
    {
    
    
        if(isprime[i])
        su[cnt++]=i;//保存素数i
        for(long long j=1;j<cnt&&su[j]*i<=maxn;j++)
        {
    
    
            isprime[su[j]*i]=0;//筛掉小于等于i的素数和i的积构成的合数
        }
    }
}
int main()
{
    
    
    int T;
    prime();
    scanf("%d",&T);
    while(T--)
    {
    
    
        int n;
        scanf("%d",&n);
        a[0]=1;
        int sum=1;
        for(int i=1;i<n;++i)
        {
    
    
            for(int j=4;;j+=2)
            {
    
    
                if(isprime[sum+j])
                {
    
    
                    a[i]=j;
                    sum+=j;
                    break;
                }
            }
        }
        for(int j=0;j<n;++j)
        {
    
    
            for(int i=0;i<n;++i)
            {
    
    
                printf("%d ",a[(i+j)%n]);
            }
            puts("");
        }
    }
    return 0;
}

C. Binäre Suche

Bestimmen Sie mithilfe des Dichotomieprozesses, wie viele Personen nach rechts und wie viele Personen nach links springen müssen, und ordnen Sie dann die Berechnungen an.

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int N=1e3+5;
int n,x,pos;
ll A[N][N];
int main()
{
    
    
    scanf("%d%d%d",&n,&x,&pos);
    A[0][0]=1;
    for(int i=1;i<=n;++i)
    {
    
    
        A[i][0]=1;
        for(int j=1;j<=i;++j)
        {
    
    
            A[i][j]=(i-j+1)*A[i][j-1]%mod;
        }
    }
    int le,gr;
    le=gr=0;
    int l=0;
    int r=n;
    while(l<r)
    {
    
    
        int mid=(l+r)>>1;
        if(mid<=pos)
        {
    
    
            if(mid!=pos)
            le++;
            l=mid+1;
        }
        else
        {
    
    
            gr++;
            r=mid;
        }
    }
    //cout<<le<<" "<<gr<<endl;
    printf("%lld\n",A[x-1][le]*A[n-x][gr]%mod*A[n-le-gr-1][n-le-gr-1]%mod);
    return 0;
}

D. Bandit in einer Stadt

Diese Frage besteht darin, die Gewichte der Blattknoten so gleichmäßig wie möglich zu gestalten. Woher weiß man also, wie man verteilt, um die Blattknoten durchschnittlich zu machen? Es muss nur vom Blattknoten nach oben gehen, um den Maximalwert des aktuellen Blattknotens, die Anzahl der Blattknoten und die Summe der Blattknotengewichte beizubehalten. Bestimmen Sie dann, ob die Gewichte aller aktuellen Blattknoten und die Summe + der Wert des aktuellen Punkts v> der Maximalwert des aktuellen Blattknotens max * die aktuelle Anzahl der Blattknoten sind. Wenn dieser Wert geringer ist, bedeutet dies, dass das Gewicht aller Blattknoten nicht bis maximal erreicht werden kann. Andernfalls alle Das Knotengewicht ist auf max. Unter Verwendung des Prinzips der Gleichverteilung wird der verbleibende Wert gleichmäßig auf jedes Blatt verteilt und max wird aktualisiert. Das Maximum des Wurzelknotens ist die Antwort.

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int head[N];
struct node
{
    
    
    int to,next;
}edge[N];
ll a[N];
struct e
{
    
    
    ll ma;
    ll num;
    ll sum;
}p[N];
int n;
int cnt;
void add(int x,int y)
{
    
    
    edge[++cnt].to=y;
    edge[cnt].next=head[x];
    head[x]=cnt;
}
void dfs(int u,int fa)
{
    
    
    bool flag=0;
    ll ma=0;
    ll s=0;
    ll nb=0;
    for(int i=head[u];i;i=edge[i].next)
    {
    
    
        flag=1;
        int v=edge[i].to;
        dfs(v,u);
        ma=max(ma,p[v].ma);
        s+=p[v].sum;
        nb+=p[v].num;
    }
    if(!flag)//р╤вс╫з╣Ц
    {
    
    
        p[u].ma=a[u];
        p[u].sum=a[u];
        p[u].num=1;
    }
    else
    {
    
    
        if(a[u]+s>ma*nb)
        {
    
    
            ll t=a[u]+s-ma*nb;
            ma+=t/nb;
            if(t%nb)
            ma++;
        }
        p[u].ma=ma;
        p[u].sum=s+a[u];
        p[u].num=nb;
    }
}
int main()
{
    
    
    scanf("%d",&n);
    for(int i=2;i<=n;++i)
    {
    
    
        int x;
        scanf("%d",&x);
        add(x,i);
    }
    for(int i=1;i<=n;++i)
    scanf("%lld",&a[i]);
    dfs(1,0);
    printf("%lld\n",p[1].ma);
    return 0;
}

E. Komplizierte Berechnungen

Wir müssen alle Elemente der letzten mex-Sequenz finden und dann prüfen, ob jedes Element im letzten mex erscheint. Wenn es sich bei einer Zahl k um eine bestimmte Folge von mex handelt, darf sie nicht in der Folge erscheinen, und 1 ~ k-1 erscheinen alle. Dann ist in der ursprünglichen Sequenz die kleinste Position von 1 ~ k-1 zu betrachten, ob sie vor der Position des letzten k erscheint. Wenn sie vor der Position des letzten k erscheint, ist mex zu diesem Zeitpunkt die kleinste, andernfalls ist es k . Dieser Prozess kann mit einem Liniensegmentbaum simuliert werden.

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n;
int a[N];
bool vis[N];//记录该数是否出现过
int last[N];//记录该数上一次出现的位置
int mi[N<<4];//维护1-k-1最小出现位置
void push_up(int k)
{
    
    
    mi[k]=min(mi[k<<1],mi[k<<1|1]);
}
void update(int k,int l,int r,int pos,int v)
{
    
    
    if(l==r)
    {
    
    
        mi[k]=v;
        return ;
    }
    int mid=(l+r)>>1;
    if(pos<=mid)
    update(k<<1,l,mid,pos,v);
    else
    update(k<<1|1,mid+1,r,pos,v);
    push_up(k);
}
int query(int k,int l,int r,int v)
{
    
    
    if(l==r)
    return l;
    int mid=(l+r)>>1;
    if(mi[k<<1]<v)
    return query(k<<1,l,mid,v);
    else
    return query(k<<1|1,mid+1,r,v);
}
int main()
{
    
    
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    scanf("%d",&a[i]);
    for(int i=1;i<=n;++i)
    {
    
    
        int x=a[i];
        if(last[x]+1<i)
        vis[query(1,1,N-1,last[x]+1)]=1;
        last[x]=i;
        update(1,1,N-1,x,i);
    }
    for(int i=1;i<=N-1;++i)
    {
    
    
        if(last[i]&&last[i]!=n)
        vis[query(1,1,N-1,last[i]+1)]=1;
    }
    vis[query(1,1,N-1,1)]=1;
    for(int i=1;i<=N-1;++i)
    {
    
    
        if(!vis[i])
        {
    
    
            printf("%d\n",i);
            return 0;
        }
    }
}

Ich denke du magst

Origin blog.csdn.net/weixin_44491423/article/details/109388667
Empfohlen
Rangfolge