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("\n");
    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\n");
            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\n");
            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\n");
    }
    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",n);
    }
    else if(k==n){
        if(n%2==0){
            for(i;i<=n;i+=2){
                if(i==n-1){
                    printf("%d %d\n",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\n",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\n",i+1,i);
                }
                else printf("%d %d ",i+1,i);
            }
            for(i=k+1;i<n;i++){
                printf("%d ",i);
            }
            printf("%d\n",n);
        }else{
            printf("%d ",1);
            for(i=2;i<=k;i+=2){
                if(i==n-1){
                    printf("%d %d\n",i+1,i);
                }
                else printf("%d %d ",i+1,i);
            }
            for(i=k+1;i<n;i++){
                printf("%d ",i);
            }
            printf("%d\n",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

 

posted @ 2021-01-25 18:23  朝暮不思  阅读(94)  评论(0编辑  收藏  举报