• 2020南京部分题解


    E题

    队友写的构造

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int maxn=1e5+5;
    string s;
    int mx,my;
    int cnt[4];
    
    void _move(int &x,int &y,int k)
    {
        if(k==0)
            y++;
        else if(k==1)
            y--;
        else if(k==2)
            x--;
        else if(k==3)
            x++;
    }
    
    void print(int k)
    {
        if(k==0)
            printf("U");
        else if(k==1)
            printf("D");
        else if(k==2)
            printf("L");
        else if(k==3)
            printf("R");
    }
    
    bool check(int a,int b,int c,int d)
    {
        int x=0,y=0;
        for(int i=1; i<=cnt[a]; i++)
        {
            _move(x,y,a);
            if(x==mx&&y==my)
                return false;
        }
        for(int i=1; i<=cnt[b]; i++)
        {
            _move(x,y,b);
            if(x==mx&&y==my)
                return false;
        }
        for(int i=1; i<=cnt[c]; i++)
        {
            _move(x,y,c);
            if(x==mx&&y==my)
                return false;
        }
        for(int i=1; i<=cnt[d]; i++)
        {
            _move(x,y,d);
            if(x==mx&&y==my)
                return false;
        }
        for(int i=1; i<=cnt[a]; i++) print(a);
        for(int i=1; i<=cnt[b]; i++) print(b);
        for(int i=1; i<=cnt[c]; i++) print(c);
        for(int i=1; i<=cnt[d]; i++) print(d);
        printf("
    ");
        return true;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(cnt,0,sizeof(cnt));
            cin>>mx>>my>>s;
            if(mx==0&&my==0)
            {
                printf("Impossible
    ");
                continue;
            }
            int ex=0,ey=0;
            for(int i=0; i<s.length(); i++)
            {
                if(s[i]=='U')
                {
                    cnt[0]++;
                    ey++;
                }
                else if(s[i]=='D')
                {
                    cnt[1]++;
                    ey--;
                }
                else if(s[i]=='L')
                {
                    cnt[2]++;
                    ex--;
                }
                else if(s[i]=='R')
                {
                    cnt[3]++;
                    ex++;
                }
            }
            if(mx==ex&&my==ey)
            {
                printf("Impossible
    ");
                continue;
            }
            bool flag=false;
            for(int i=0; i<4; i++)
            {
                if(flag==true)
                    continue;
                for(int j=0; j<4; j++)
                {
                    if(i==j||flag==true)
                        continue;
                    for(int k=0; k<4; k++)
                    {
                        if(k==i||k==j||flag==true)
                            continue;
                        for(int m=0; m<4; m++)
                        {
                            if(m==i||m==j||m==k||flag==true)
                                continue;
                            flag=check(i,j,k,m);
                        }
                    }
                }
            }
            if(flag==false)
                printf("Impossible
    ");
        }
        return 0;
    }
    View Code

    K题

    队友写的签到

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+10;
    int main(){
        int n,k;
        cin>>n>>k;
        int i=1;
        if(k==0){
            cout<<"-1"<<endl;
            return 0;
        }
        if(n==1){
            cout<<"1"<<endl;
            return 0;
        }
        if(k==1){
            for(i;i<n;i++)printf("%d ",i);
            printf("%d
    ",n);
        }
        else if(k==n){
            if(n%2==0){
                for(i;i<=n;i+=2){
                    if(i==n-1){
                        printf("%d %d
    ",i+1,i);
                    }
                    else printf("%d %d ",i+1,i);
                }
            }
            else{
                cout<<1<<endl;
                for(i=2;i<=n;i+=2){
                    if(i==n-1){
                        printf("%d %d
    ",i+1,i);
                    }
                    else printf("%d %d ",i+1,i);
                }
            }
        }
        else{
            if(k%2==0){
                for(i;i<=k;i+=2){
                    if(i==n-1){
                        printf("%d %d
    ",i+1,i);
                    }
                    else printf("%d %d ",i+1,i);
                }
                for(i=k+1;i<n;i++){
                    printf("%d ",i);
                }
                printf("%d
    ",n);
            }else{
                printf("%d ",1);
                for(i=2;i<=k;i+=2){
                    if(i==n-1){
                        printf("%d %d
    ",i+1,i);
                    }
                    else printf("%d %d ",i+1,i);
                }
                for(i=k+1;i<n;i++){
                    printf("%d ",i);
                }
                printf("%d
    ",n);
            }
        }
    }
    View Code

    L题

    容易想到的是,根据位置大小,就是求取将所有ab按距离排序后,最长的连续a是多少

    注意当距离相等时,a不能算

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=2e6+10;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    int a[N];
    int b[N];
    int sign[N];
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n,m;
            cin>>n>>m;
            int i,j;
            for(i=1;i<=n;i++){
                cin>>a[i];
            }
            for(i=1;i<=m;i++){
                cin>>b[i];
            }
            sort(a+1,a+1+n);
            sort(b+1,b+1+m);
            int cnt=0;
            for(i=1,j=1;i<=n&&j<=m;){
                if(a[i]>b[j]){
                    sign[++cnt]=1;
                    j++;
                }
                else if(a[i]<b[j]){
                    sign[++cnt]=2;
                    i++;
                }
                else{
                    sign[++cnt]=1;
                    while(a[i]==b[j]){
                        i++;
                    }
                    j++;
                }
            }
            while(i<=n){
                sign[++cnt]=2;
                i++;
            }
            while(j<=m){
                sign[++cnt]=1;
                j++;
            }
            int ans=0;
            int tmp=0;
            for(i=1;i<=cnt;i++){
                if(sign[i]==1){
                    tmp=0;
                    continue;
                }
                tmp++;
                ans=max(ans,tmp);
            }
            if(!ans){
                cout<<"Impossible"<<endl;
            }
            else{
                cout<<ans<<endl;
            }
        }
    }
    View Code

    M题

    题目给的信息基本上可以推出状态

    初始的树形dp可以写成f[i][j][k]表示以i为根,删了j个,当前i有没有删

    第三维是因为我们要根据i的状态确定最后的答案

    我写的更新t掉了,因为复杂度不正确,正确的复杂度是枚举到子树大小,因为这样可以保证两两点只相互更新一次

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e6+10;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    int h[N],ne[N],e[N],idx;
    ll a[N],p[N];
    ll f[2020][2020][2];
    int depth[N];
    int sz[N];
    ll sum[N];
    struct node{
        int a;
        ll b;
        int c;
    };
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    void dfs(int u,int fa){
        int i;
        sz[u]=1;
        f[u][0][0]=a[u];
        f[u][1][1]=0;
        ll res=0;
        int j,k;
        ll tmp[2020][2];
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            dfs(j,u);
            for(int x=0;x<=sz[u]+sz[j];x++){
                tmp[x][0]=tmp[x][1]=1e18;
            }
            for(int x=0;x<=sz[u];x++){
                for(int y=0;y<=sz[j];y++){
                    tmp[x+y][0]=min(tmp[x+y][0],f[u][x][0]+f[j][y][0]+a[j]);
                    tmp[x+y][0]=min(tmp[x+y][0],f[u][x][0]+f[j][y][1]);
                    tmp[x+y][1]=min(tmp[x+y][1],f[u][x][1]+f[j][y][0]);
                    tmp[x+y][1]=min(tmp[x+y][1],f[u][x][1]+f[j][y][1]);
                }
            }
            sz[u]+=sz[j];
            for(int i=0;i<=sz[u];i++)
                f[u][i][0]=tmp[i][0],f[u][i][1]=tmp[i][1];
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            idx=0;
            int i;
            for(i=0;i<=n;i++){
                h[i]=-1;
            }
            for(i=2;i<=n;i++){
                cin>>p[i];
                add(i,p[i]);
                add(p[i],i);
            }
            for(i=1;i<=n;i++){
                cin>>a[i];
                sum[i]=a[i];
            }
            for(i=1;i<=n;i++){
                for(int j=0;j<=n;j++){
                    f[i][j][0]=f[i][j][1]=1e18;
                }
            }
            for(i=1;i<=n;i++){
                sum[p[i]]+=a[i];
            }
            depth[1]=1;
            dfs(1,-1);
            ll ans=0;
            for(i=1;i<=n;i++){
                ans+=sum[i];
            }
            for(i=0;i<=n;i++){
                cout<<min(f[1][i][0],f[1][i][1])<<" ";
            }
            cout<<endl;
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    Hadoop命令手册
    编程算法
    综合8种子排序算法总结和比较
    android 创建一个新的每次project什么时候 请问自己主动 参加 V7依赖?
    【JDBC】java PreparedStatement操作oracle数据库
    【cocos2dx 加载资源目录】
    Project Euler:Problem 39 Integer right triangles
    矿Java开发学习之旅------&gt;Java排序算法经典的二分法插入排序
    [React Intl] Render Content with Placeholders using react-intl FormattedMessage
    [React Intl] Install and Configure the Entry Point of react-intl
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14326755.html
Copyright © 2020-2023  润新知