1. 程式人生 > >bestcoder round 74 div2

bestcoder round 74 div2

coder sin std CP flag 最短路 cpp oid IT

隨便看了一場以前的bestcoder,然後順便寫了一下,都不碼的樣子

有中文題面,這裏就不寫題目大意了

T1.

剛開始想復雜了,T1可能是4道題裏面想的最久的

我們大概弄一下就可以發現,如果a[i]>0,並且a[i+1]滿足條件,那麽s[i]=s[i+1]

所以我們發現其實是一堆相同的弄在一起。

當然如果a[i]=0那麽說明s[i]!=s[i-1],這樣i就有25種選法,剛開始有26種選法

就是ans=26*25^(a[i]==0的個數)

我們考慮什麽時候答案=0,顯然a[i]!=0&&a[i]!=a[i+1]+1那麽就不合法了

代碼:

#include<bits/stdc++.h>
#define N 2000005
#define Mod 1000000007
using namespace std;
int n,T,ans,a[N];
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);n--;ans=26;
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);a[n+1]=0;
        for (int i=1;i<=n;i++)
            if (a[i]!=a[i+1]+1&&a[i]!=0) ans=0;
        for (int i=1;i<=n;i++)
            if (!a[i]) ans=1ll*ans*25%Mod;
        printf("%d\n",ans);
    }
    return 0;
}

T2.

因為只有3條邊,顯然不會重復走,最短路一定是正常走+走加入的三條路

那麽只要枚舉一下3條路的排列,然後方向判斷一下,dfs就ok了

代碼:

#include<bits/stdc++.h>
#define N 500005
#define Mod 1000000007
using namespace std;
int T,n,m,a[N],b[N],s,t,ans,sum;bool use[5];
void dfs(int now,int tot){
    if (tot+abs(now-t)<ans) ans=tot+abs(now-t);
    for (int i=1;i<=3;i++){
        if (use[i]) continue;
        use[i]=1;
        dfs(a[i],tot+1+abs(now-b[i]));
        dfs(b[i],tot+1+abs(now-a[i]));
        use[i]=0;
    }
}
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=3;i++) scanf("%d%d",&a[i],&b[i]);
        for (int i=1;i<=m;i++){
            ans=1e9;scanf("%d%d",&s,&t);
            dfs(s,0);
            sum=(sum+1ll*i*ans%Mod)%Mod;
        }
        printf("%d\n",sum);sum=0;
    }
    return 0;
}

T3.

對於第一個操作,其實等價於xor一個2^x

其實原問題等價於求0-->S^T的最少操作次數

我們發現n<=15,所以我們對於a[i]暴力dfs求出用這些數組成的數的最小次數

dp[i]表示構成i的最小次數

然後考慮操作1

因為都是xor一個2的次方數,所以每一位都是相互獨立的

如果x^3是最優的,那麽x^1一定是最優的,然後x^1^2也隨之一定是最優的

所以我們把x從0到15枚舉一下

然後再枚舉i的值,更新一下dp值即可

一般的位運算的題,都是先枚舉次方再枚舉i的

代碼:

#include<bits/stdc++.h>
#define N 1000005
#define Mod 1000000007
using namespace std;
int T,n,m,s,t,ans,a[N],mp[N];
void dfs(int u,int dep,int sum){
    if (mp[sum]>dep) mp[sum]=dep;
    if (u==n+1) return;
    dfs(u+1,dep+1,sum^a[u]);
    dfs(u+1,dep,sum);
}
int main(){
    scanf("%d",&T);
    while (T--){
        scanf("%d%d",&n,&m);
        memset(mp,127,sizeof(mp));
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        dfs(1,0,0);
        for (int j=0;j<=17;j++)
            for (int i=0;i<=(1<<18);i++)
                if (mp[i^(1<<j)]>mp[i]+1) mp[i^(1<<j)]=mp[i]+1;
        for (int i=1;i<=m;i++){
            scanf("%d%d",&s,&t);
            //cerr<<mp[s^t]<<endl;
            ans=(ans+1ll*mp[s^t]*i%Mod)%Mod;
        }
        printf("%d\n",ans);ans=0;
    }
    return 0;
}

T4.

感覺T2-T4都沒啥難度,還是T1最難(┭┮﹏┭┮)<----弱

顯然的貪心,如果當前剩下的點中最小的點能夠通過刪邊來得到,那麽就刪那個條數

註意我們不用考慮刪的是哪些邊

因為這個點拓撲了,那麽意味著從它出發的邊都要刪除,所以不用知道具體哪些,只要知道這個點是不是要刪即可

然後用一個堆來維護一下點的大小值即可

代碼:

#include<bits/stdc++.h>
#define N 2000005
#define Mod 1000000007
using namespace std;
int n,m,k,T,x,y,kk,head[N],ru[N];bool use[N],flag[N];
struct Edge{int nxt,to;}e[N];
priority_queue<int,vector<int>,greater<int> > Q;
inline void link(int x,int y){e[++kk].nxt=head[x];e[kk].to=y;head[x]=kk;}
int main(){
    scanf("%d",&T); 
    while (T--){
        scanf("%d%d%d",&n,&m,&k);
        memset(ru,0,sizeof(ru));
        kk=0;memset(head,0,sizeof(head));
        while (!Q.empty()) Q.pop();
        for (int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            link(x,y);ru[y]++;
        }
        for (int i=1;i<=n;i++){
            if (ru[i]<=k) Q.push(i),flag[i]=0;
            else flag[i]=1;
        }
        long long ans=0,tot=0;
        while (!Q.empty()){
            while (ru[Q.top()]>k){flag[Q.top()]=1;Q.pop();}
            int x=Q.top();int y=ru[x];
            //printf("WTF%d\n",x);
            ru[x]=0;k-=y;
            Q.pop();ans=(ans+1ll*(++tot)*x%Mod)%Mod;
            for (int i=head[x];i;i=e[i].nxt){
                int v=e[i].to;
                if (ru[v]<=k+1&&ru[v]>0&&flag[v]){flag[v]=0;Q.push(v);}
                ru[v]--;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

  

bestcoder round 74 div2