2016ccpc 网络选拔赛题解

A  模拟大数取模

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 10000000 + 1;
const int mod = 10001;
char s[maxn];
int main(){
    int kase = 0;
    while(scanf("%s",s) == 1){
        int len = strlen(s);
        int v = 0;
        for (int i = 0; i < len; ++i){
            v = (v*10 + s[i]-48) % mod;
        }
        if (v == 0)printf("Case #%d: YES\n",++kase);
        else printf("Case #%d: NO\n",++kase);
    }
    return 0;
}
View Code

B  高斯消元(zwz口胡会写,未实现)

C 换根dp维护

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=5e5+10;
const int inf=0x3f3f3f3f;
const ll mod=998244353;
int a[N],n;
int h[N],ne[N],e[N],w[N],idx;
int f[N][2],g[N][2];
int id[N];
void add(int a,int b,int c){
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
void dfs(int u,int fa){
    f[u][0]=f[u][1]=a[u];
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
            continue;
        dfs(j,u);
        f[u][1]+=max(0,f[j][0]-2*w[i]);
        if(f[u][0]+f[j][1]-w[i]>f[u][1]){
            f[u][1]=f[u][0]+f[j][1]-w[i];
            id[u]=j;
        }
        f[u][0]+=max(0,f[j][0]-2*w[i]);
    }
}
void get(int u,int fa){
    if(f[u][0]+g[u][1]>f[u][1]+g[u][0]){
        id[u]=fa;
    }
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
            continue;
        if(j==id[u]){
            int tmp1=g[u][1]+a[u],tmp2=g[u][0]+a[u];//tmp1目前是父亲往上的停留点,tmp2目前是回到父亲的点
            for(int k=h[u];k!=-1;k=ne[k]){
                int v=e[k];
                if(v==j||v==fa)
                    continue;
                tmp1+=max(0,f[v][0]-2*w[k]);
                if(tmp2+max(f[v][1]-w[k],0)>tmp1){
                    tmp1=tmp2+max(0,f[v][1]-w[k]);
                }
                tmp2+=max(0,f[v][0]-2*w[k]);
            }
            g[j][0]=max(0,tmp2-2*w[i]);//回到当前点的最大值
            g[j][1]=max(0,tmp1-w[i]);//停留在上面的最大值
        }
        else{
            int tmp;
            if(f[j][0]>=2*w[i]){
                tmp=f[j][0]-2*w[i];
            }
            else{
                tmp=0;
            }
            g[j][0]=max(0,f[u][0]+g[u][0]-tmp-2*w[i]);
            g[j][1]=max(0,max(g[u][1]+f[u][0]-tmp-w[i],f[u][1]+g[u][0]-tmp-w[i]));
        }
        get(j,u);
    }
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    int cnt=1;
    while(t--){
        cin>>n;
        int i;
        idx=0;
        for(i=0;i<=n;i++){
            h[i]=-1;
            f[i][1]=f[i][0]=g[i][1]=g[i][0]=0;
            id[i]=-1;
        }
        for(i=1;i<=n;i++)
            cin>>a[i];
        for(i=1;i<n;i++){
            int a,b,c;
            cin>>a>>b>>c;
            add(a,b,c);
            add(b,a,c);
        }
        dfs(1,-1);
        get(1,-1);
        cout<<"Case #"<<cnt++<<":"<<endl;
        for(i=1;i<=n;i++){
            cout<<(max(f[i][0]+g[i][1],f[i][1]+g[i][0]))<<endl;
        }
    }
    return 0;
}
View Code

D 贪心乱搞,我的做法是排序后枚举贪心查看情况

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=5e5+10;
const int inf=0x3f3f3f3f;
const ll mod=998244353;
int a[N];
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    int idx=1;
    while(t--){
        int n;
        cin>>n;
        int i;
        int sum=0;
        for(i=1;i<=n;i++){
            cin>>a[i];
            sum+=a[i];
        }
        sort(a+1,a+1+n);
        int tmp=0;
        int cnt=0;
        for(i=1;i<=n;i++){
            if(i==n){
                if(sum-tmp-1>=tmp+1){
                    cnt++;
                    break;
                }
            }
            if(cnt+(2*a[i])<=sum-tmp-2*a[i]){
                a[i+1]-=a[i];
                cnt+=2*a[i];
                tmp+=2*a[i];
            }
            else{
                int j;
                for(j=1;j<=a[i];j++){
                    if(cnt+2*j>sum-tmp-2*j){
                        if(cnt+2*j-1<=sum-tmp-2*j+1){
                            cnt+=2*j-1;
                            break;
                        }
                        else{
                            cnt+=2*(j-1);
                            break;
                        }
                    }
                }
                break;
            }
        }
        cout<<"Case #"<<idx++<<": ";
        cout<<cnt<<endl;
    }
    return 0;
}
View Code

G 状压dp+容斥原理

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=5e5+10;
const int inf=0x3f3f3f3f;
const int mod=772002;
int n,m;
int f[30][1200];
char g[30][30];
char tmp[30][30];
map<int,pll> m1;
int pos[N],mou[N];
ll ans;
int dx[]={-1,-1,0,1,1,1,0,-1};
int dy[]={0,1,1,1,0,-1,-1,-1};
int sx[N],sy[N];
bool check(){
    int i,j;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(g[i][j]!='X')
                continue;
            for(int k=0;k<8;k++){
                int x=i+dx[k];
                int y=j+dy[k];
                if(x&&x<=n&&y&&y<=m){
                    if(g[x][y]=='X')
                        return true;
                }
            }
        }
    }
    return false;
}
ll solve(){
    int i,j;
    memset(f,0,sizeof f);
    f[0][0]=1;
    int cnt=0;
    int num=n*m;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(g[i][j]=='X'){
                cnt++;
                sx[cnt-1]=i;
                sy[cnt-1]=j;
            }
        }
    }
    memset(tmp,'.',sizeof tmp);
    int mx=1<<cnt;
    for(i=0;i<mx;i++){
        mou[i]=0;
        for(j=0;j<cnt;j++){
            if(i>>j&1){
                mou[i]++;
            }
            else{
               tmp[sx[j]][sy[j]]='Y';
            }
        }
        pos[i]=num-cnt;
        for(int l=1;l<=n;l++){
            for(int r=1;r<=m;r++){
                if(g[l][r]=='X')
                    continue;
                for(int k=0;k<8;k++){
                    int a=l+dx[k];
                    int b=r+dy[k];
                    if(a<=n&&a&&b&&b<=m){
                        if(tmp[a][b]=='Y'){
                            pos[i]--;
                            break;
                        }
                    }
                }
            }
        }
        for(int k=0;k<cnt;k++){
            tmp[sx[k]][sy[k]]='.';
        }
    }
    for(i=0;i<num;i++){
        for(j=0;j<mx;j++){
            if(!f[i][j])
                continue;
            for(int k=0;k<cnt;k++){
                if(!((j>>k)&1)){
                    f[i+1][j|(1<<k)]=(f[i+1][j|(1<<k)]+f[i][j])%mod;
                }
            }
            f[i+1][j]=(f[i+1][j]+f[i][j]*(pos[j]-i+mou[j])%mod)%mod;
        }
    }
    return f[num][mx-1];
}
void dfs(int u,int num){
    if(u==n*m+1){
        if(num%2==0)
            ans=(ans+solve())%mod;
        else
            ans=(ans-solve()+mod)%mod;
        return ;
    }
    int x=m1[u].first;
    int y=m1[u].second;
    int i;
    for(i=0;i<8;i++){
        int a=x+dx[i];
        int b=y+dy[i];
        if(a&&a<=n&&b&&b<=m){
            if(g[a][b]=='X')
                break;
        }
    }
    if(i==8&&g[x][y]=='.'){
        g[x][y]='X';
        dfs(u+1,num+1);
        g[x][y]='.';
    }
    dfs(u+1,num);
}
int main(){
    ios::sync_with_stdio(false);
    int times=1;
    while(cin>>n>>m){
        m1.clear();
        int i,j;
        int id=0;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                cin>>g[i][j];
                m1[++id]={i,j};
            }
        }
        if(check()){
            cout<<"Case #"<<times++<<": ";
            cout<<0<<endl;
        }
        else{
            ans=0;
            dfs(1,0);
            cout<<"Case #"<<times++<<": ";
            cout<<ans<<endl;
        }
    }
    return 0;
}
View Code

J Trie+启发式合并

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=2e5+10;
const int M=2e6+10;
const int inf=0x3f3f3f3f;
const int mod=772002;
int h[N],ne[N],e[N],idx;
int n,tr[M][2],rt[N];
int w[N],times;
int ans[N];
int p[M],val[M];
int sum[M];
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int query(int u,int k,int dep){
    if(dep==-1)
        return val[u];
    int sign=(k>>dep)&1;
    if(tr[u][sign])
        return query(tr[u][sign],k,dep-1);
    else
        return query(tr[u][sign^1],k,dep-1);
}
void pushup(int u,int dep){
    int l=tr[u][0],r=tr[u][1];
    sum[u]=sum[l]+sum[r];
    if(sum[l]==1&&sum[r]==1){
        p[u]=p[l]^p[r];
    }
    else if(!sum[l]||!sum[r]){
        p[u]=sum[l]?p[l]:p[r];
    }
    else if(sum[l]>1&&sum[r]>1){
        p[u]=max(p[l],p[r]);
    }
    else{
        if(sum[l]!=1)
            swap(l,r);
        p[u]=p[l]^query(r,p[l],dep-1);
    }
}
void insert(int &u,int dep,int k){
    int i;
    if(!u)
        u=++times;
    if(dep==-1){
        sum[u]=1;
        p[u]=val[u]=k;
        return ;
    }
    if(k>>dep&1)
    insert(tr[u][1],dep-1,k);
    else
    insert(tr[u][0],dep-1,k);
    pushup(u,dep);
}
int Merge(int u,int v,int dep){
    int i;
    if(!u||!v)
        return u|v;
    if(dep==-1){
        sum[u]+=sum[v];
        if(sum[u]>1){
            p[u]=0;
        }
        else{
            p[u]=val[u];
        }
        return u;
    }
    tr[u][0]=Merge(tr[u][0],tr[v][0],dep-1);
    tr[u][1]=Merge(tr[u][1],tr[v][1],dep-1);
    pushup(u,dep);
    return u;
}
void dfs(int u,int fa){
    insert(rt[u],16,w[u]);
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
            continue;
        dfs(j,u);
        rt[u]=Merge(rt[u],rt[j],16);
    }
    if(sum[rt[u]]>1)
        ans[u]=p[rt[u]];
}
void init(){
    int i;
    times=0,idx=0;
    memset(h,-1,sizeof h);
    memset(sum,0,sizeof sum);
    memset(ans,-1,sizeof ans);
    memset(rt,0,sizeof rt);
    memset(tr,0,sizeof tr);
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    int cnt=1;
    while(t--){
        cin>>n;
        int i;
        init();
        for(i=1;i<=n;i++){
            cin>>w[i];
        }
        for(i=1;i<n;i++){
            int a,b;
            cin>>a>>b;
            add(a,b);
            add(b,a);
        }
        dfs(1,-1);
        int m;
        cin>>m;
        cout<<"Case #"<<cnt++<<":"<<endl;
        while(m--){
            int u;
            cin>>u;
            cout<<ans[u]<<endl;
        }
    }
    return 0;
}
View Code

K 水题map去重

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=5e5+10;
const int inf=0x3f3f3f3f;
const ll mod=998244353;
map<char,int> m1;
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    int cnt=1;
    while(t--){
        string s;
        cin>>s;
        int i;
        m1.clear();
        for(i=0;i<s.size();i++){
           m1[s[i]]++;
        }
        cout<<"Case #"<<cnt++<<": ";
        cout<<(int)m1.size()<<endl;
    }
    return 0;
}
View Code

 

posted @ 2020-09-02 16:43  朝暮不思  阅读(171)  评论(0编辑  收藏  举报