• AtCoder Grand Contest 004题解


    传送门

    (A)

    咕咕

    int a,b,c;
    int main(){
    	scanf("%d%d%d",&a,&b,&c);
    	if((a&1^1)|(b&1^1)|(c&1^1))return puts("0"),0;
    	printf("%lld
    ",min(1ll*a*b,min(1ll*a*c,1ll*b*c)));
    	return 0;
    }
    

    (B)

    一开始想歪了……

    枚举$2$操作的次数$k$,然后用单调队列优化就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    const int N=5005;const ll inf=1e18;
    int a[N],q[N],n,x,k;ll res;
    void solve(){
    	int h=1,t=0;ll sum=0;
    	fp(i,1,n){
    		while(h<=t&&a[i]<=a[q[t]])--t;
    		q[++t]=i;
    	}
    	fp(i,n+1,n<<1){
    		while(h<=t&&i-q[h]>k)++h;
    		while(h<=t&&a[i]<=a[q[t]])--t;
    		q[++t]=i,sum+=a[q[h]];
    	}
    	cmin(res,sum+1ll*k*x);
    }
    int main(){
    	scanf("%d%d",&n,&x);res=inf;
    	fp(i,1,n)scanf("%d",&a[i]),a[i+n]=a[i];
    	for(k=0;k<n;++k)solve();
    	printf("%lld
    ",res);
    	return 0;
    }
    

    (C)

    比较秒的思路然而我并没有想出来

    只要把它给染成两个$E$的样子,紫色的部分都染掉就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    using namespace std;
    const int N=1005;
    char mp[N][N],s[N][N];int n,m;
    int main(){
    	scanf("%d%d",&n,&m);
    	fp(i,1,n)scanf("%s",mp[i]+1);
    	fp(i,1,n)fp(j,1,m)s[i][j]=mp[i][j];
    	fp(i,1,n)s[i][1]='#';for(R int i=1;i<=n;i+=2)fp(j,1,m-1)s[i][j]='#';
    	fp(i,1,n){
    		fp(j,1,m)putchar(s[i][j]);
    		putchar('
    ');
    	}
    	putchar('
    ');
    	fp(i,1,n)fp(j,1,m)s[i][j]=mp[i][j];
    	fp(i,1,n)s[i][m]='#';for(R int i=2;i<=n;i+=2)fp(j,2,m)s[i][j]='#';
    	fp(i,1,n){
    		fp(j,1,m)putchar(s[i][j]);
    		putchar('
    ');
    	}
    	return 0;
    }
    

    (D)

    显然会连成一棵树,那么把所有深度大于$k$的点取出来,每一次贪心取出深度最大的点,并把它的$k-1$次父亲的$fa$置为$1$就好了

    顺便注意$1$必须连上自己否则构成的这个环李必然有点不满足条件

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    using namespace std;
    const int N=1e5+5;
    struct eg{int v,nx;}e[N<<1];int head[N],tot;
    inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
    int dep[N],fa[N],id[N],vis[N],n,k,top,res;
    inline bool cmp(const int &x,const int &y){return dep[x]>dep[y];}
    void dfs(int u){
    	if(dep[u]>k)id[++top]=u;
    	go(u)dep[v]=dep[u]+1,dfs(v);
    }
    void clr(int u){vis[u]=1;go(u)if(!vis[v])clr(v);}
    inline void jump(R int u){fp(i,1,k-1)u=fa[u];clr(u);++res;}
    int main(){
    	scanf("%d%d",&n,&k);
    	fp(i,1,n)scanf("%d",&fa[i]);
    	fp(i,2,n)add(fa[i],i);
    	dfs(1);
    	sort(id+1,id+1+top,cmp);
    	fp(i,1,top)if(!vis[id[i]])jump(id[i]);
    	printf("%d
    ",res+(fa[1]!=1));
    	return 0;
    }
    

    (E)

    果然我的$dp$菜的跟什么一样的……

    首先把机器人的移动看做出口的移动,那么如果出口往左移动了一格,它在右边就会有一整列不能走,走其他方向同理

    那么我们记一个$dp[u][d][l][r]$表示分别往四个方向最多走了多少,转移的时候用前缀和优化一下就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    using namespace std;
    const int N=105;
    short f[N][N][N][N],col[N][N],row[N][N],res;
    char mp[N][N];int n,m,x,y;
    inline int min(R int x,R int y){return x<y?x:y;}
    inline int max(R int x,R int y){return x>y?x:y;}
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d%d",&n,&m);
    	fp(i,1,n){
    		scanf("%s",mp[i]+1);
    		fp(j,1,m){
    			if(mp[i][j]=='E')x=i,y=j;
    			col[i][j]=col[i][j-1]+(mp[i][j]=='o'),
    			row[i][j]=row[i-1][j]+(mp[i][j]=='o');
    		}
    	}
    	fp(u,0,x-1)fp(d,0,n-x)if(u+d<max(x,n-x+1))
    		fp(l,0,y-1)fp(r,0,m-y)if(l+r<max(y,m-y+1)){
    			R short &ret=f[u][d][l][r];
    			int tl=max(r+1,y-l),tr=min(y+r,m-l),tu=max(d+1,x-u),td=min(x+d,n-u);
    			if(u+1+d<x)cmax(f[u+1][d][l][r],short(ret+col[x-u-1][tr]-col[x-u-1][tl-1]));
    			if(d+1+u<=n-x)cmax(f[u][d+1][l][r],short(ret+col[x+d+1][tr]-col[x+d+1][tl-1]));
    			if(l+1+r<y)cmax(f[u][d][l+1][r],short(ret+row[td][y-l-1]-row[tu-1][y-l-1]));
    			if(r+1+l<=m-y)cmax(f[u][d][l][r+1],short(ret+row[td][y+r+1]-row[tu-1][y+r+1]));
    			cmax(res,ret);
    		}
    	printf("%d
    ",res);
    	return 0;
    }
    

    (F)

    好麻烦,不写了

  • 相关阅读:
    python 进程
    python 网络编程
    Tensorflow学习教程------参数保存和提取重利用
    Tensorflow学习教程------利用卷积神经网络对mnist数据集进行分类_利用训练好的模型进行分类
    Tensorflow学习教程------利用卷积神经网络对mnist数据集进行分类_训练模型
    Tensorflow学习教程------tensorboard网络运行和可视化
    Tensorflow学习教程------过拟合
    Spring的@Value注解为静态变量赋值
    Linux使用scp远程拷贝使用ssh免密登录
    Mysql升级5.7.10后GROUP BY语句出错解决方法
  • 原文地址:https://www.cnblogs.com/yuanquming/p/11360262.html
Copyright © 2020-2023  润新知