• AGC004(A~E)


    前言

    \(F\)不会做,正解好神仙,爬了

    正题


    AT2041 [AGC004A] Divide a Cuboid

    https://www.luogu.com.cn/problem/AT2041

    题目大意

    一个\(A*B*C\)的立方体,分成两个长方体使得边长都是整数而且体积差最小。

    \(1\leq A,B,C\leq 10^9\)

    解题思路

    如果有一边是偶数之间这边开始分,不然就找一边分的最小就好了。

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    ll a,b,c;
    signed main()
    {
    	scanf("%lld%lld%lld",&a,&b,&c);
    	if((a&1)&&(b&1)&&(c&1))printf("%lld\n",min(a*b,min(b*c,a*c)));
    	else puts("0");
    	return 0;
    }
    

    AT2042 [AGC004B] Colorful Slimes

    https://www.luogu.com.cn/problem/AT2042

    题目大意

    \(n\)个颜色的史莱姆,第\(i\)只可以花费\(a_i\)获得,或者花费\(k\)使得所有获得的史莱姆颜色加一后模\(n\),求最少花费多少能获得所有颜色的史莱姆。

    \(1\leq n\leq 2000,1\leq a_i,k\leq 10^9\)

    解题思路

    显然我们可以通过控制获得的顺序使得加一的次数就是次数最多的那个史莱姆,所以处理出最多加\(i\)次的情况下每个史莱姆的最少获得费用。
    然后枚举就好了。时间复杂度:\(O(n^2)\)

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const ll N=2100;
    ll n,k,ans,a[N],f[N][N];
    signed main()
    {
    	scanf("%lld%lld",&n,&k);
    	for(ll i=0;i<n;i++)
    		scanf("%lld",&a[i]);
    	for(ll i=0;i<n;i++){
    		f[i][0]=a[i];
    		for(ll j=1;j<n;j++)
    			f[i][j]=min(f[i][j-1],a[(i-j+n)%n]);
    	}
    	ans=1e18;
    	for(ll i=0;i<n;i++){
    		ll sum=0;
    		for(ll j=0;j<n;j++)
    			sum+=f[j][i];
    		ans=min(ans,sum+i*k);
    	}
    	printf("%lld\n",ans);
    	return 0;
    }
    

    AT2043 [AGC004C] AND Grid

    https://www.luogu.com.cn/problem/AT2043

    题目大意

    给出一个\(n\times m\)的网格图,满足四边上都没有'#',现在要求求出两个\(n\times m\)的网格图使得上面的'#'四联通且两张图上'#'的并恰好是给出的网格图。

    \(1\leq n,m\leq 500\)

    解题思路

    突破口应该是四周没有'#',所以我们可以用四周来保证四联通,然后从四周延伸'#'过来。

    对于第一张图我们左边铺满'#',奇数行除了最右边铺满'#',偶数行只在有原图有'#'的位置铺。

    第二张图相反的右边铺满'#',偶数行处理最左边铺满'#',奇数行在原图有'#'的位置铺。

    就好了。

    code

    #include<bits/stdc++.h>
    using namespace std;
    const int N=510;
    int n,m;char s[N][N];
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		scanf("%s",s[i]+1);
    	for(int i=1;i<=n;i++){
    		putchar('#');
    		if(i==1||i==n)
    			for(int j=2;j<=m;j++)putchar('.');
    		else if(i&1)
    			for(int j=2;j<=m;j++)putchar((j==m)?'.':'#');
    		else 
    			for(int j=2;j<=m;j++)putchar(s[i][j]);
    		putchar('\n');
    	}
    	putchar('\n');
    	for(int i=1;i<=n;i++){
    		if(i==1||i==n)
    			for(int j=1;j<m;j++)putchar('.');
    		else if(!(i&1))
    			for(int j=1;j<m;j++)putchar((j==1)?'.':'#');
    		else 
    			for(int j=1;j<m;j++)putchar(s[i][j]);
    		putchar('#');putchar('\n');
    	}
    	return 0;
    }
    

    AT2044 [AGC004D] Teleporter

    https://www.luogu.com.cn/problem/AT2044

    题目大意

    给出\(n\)个点的一棵基环外向树,保证一号点在环上,每次可以修改一个点的父亲(可以是自己),求最少修改次使得所有点的\(k\)级祖先都是\(1\)号点。

    \(1\leq n\leq 10^5,1\leq k\leq 10^9\)

    解题思路

    显然一号点一定要连自己,因为环上必然只有一个点满足\(k\)级祖先是\(1\),所以改其他节点还不如改一号点。

    然后问题就变成树上的了,之间贪心到必须改的时候再改就好了。

    时间复杂度:\(O(n)\)

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1e5+10;
    struct node{
    	int to,next;
    }a[N<<1];
    int n,k,tot,ans,fa[N],ls[N],f[N];
    void addl(int x,int y){
    	a[++tot].to=y;
    	a[tot].next=ls[x];
    	ls[x]=tot;return;
    }
    void dfs(int x){
    	f[x]=0;
    	for(int i=ls[x];i;i=a[i].next){
    		int y=a[i].to;
    		if(y==fa[x])continue;
    		dfs(y);f[x]=max(f[x],f[y]+1);
    	}
    	if(fa[x]!=1&&f[x]+1>=k)ans++,f[x]=-1;
    	return;
    }
    int main()
    {
    	scanf("%d%d",&n,&k);
    	scanf("%d",&fa[1]);
    	if(fa[1]!=1)ans++;fa[1]=1;
    	for(int i=2;i<=n;i++){
    		scanf("%d",&fa[i]);
    		addl(fa[i],i);
    	}
    	dfs(1);
    	printf("%d\n",ans);
    	return 0;
    }
    

    AT2045 [AGC004E] Salvage Robots

    题目大意

    \(n\times m\)的网格上有一些机器人和一个出口,每次你可以让所有的机器人上/左/下/右移动,出界的机器人算为死亡,到达出口的机器人算为出逃,求最多能救走多少个机器人。

    \(1\leq n,m\leq 100\)

    解题思路

    \(f_{u,d,l,r}\)表示所有机器人最多往上/下/左/右走了\(u/d/l/r\)步时最多能救多少机器人,然后暴力转移即可。

    时间复杂度:\(O(n^4)\)

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=105;
    int n,m,rx,ry,ans,w[N][N],h[N][N];
    short f[N][N][N][N];char s[N];
    signed main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%s",s+1);
    		for(int j=1;j<=m;j++){
    			w[i][j]=w[i-1][j]+(s[j]=='o');
    			h[i][j]=h[i][j-1]+(s[j]=='o');
    			if(s[j]=='E')rx=i,ry=j;
    		}
    	}
    	for(int u=0;u<rx;u++)
    		for(int d=0;d<=n-rx;d++)
    			for(int l=0;l<ry;l++)
    				for(int r=0;r<=m-ry;r++){
    					ans=max(ans,(int)f[u][d][l][r]);
    					if(l+r<ry-1)f[u][d][l+1][r]=max((int)f[u][d][l+1][r],f[u][d][l][r]+w[min(rx+d,n-u)][ry-l-1]-w[max(rx-u-1,d)][ry-l-1]);
    					if(l+r<m-ry)f[u][d][l][r+1]=max((int)f[u][d][l][r+1],f[u][d][l][r]+w[min(rx+d,n-u)][ry+r+1]-w[max(rx-u-1,d)][ry+r+1]);
    					if(u+d<rx-1)f[u+1][d][l][r]=max((int)f[u+1][d][l][r],f[u][d][l][r]+h[rx-u-1][min(ry+r,m-l)]-h[rx-u-1][max(ry-l-1,r)]);
    					if(u+d<n-rx)f[u][d+1][l][r]=max((int)f[u][d+1][l][r],f[u][d][l][r]+h[rx+d+1][min(ry+r,m-l)]-h[rx+d+1][max(ry-l-1,r)]);
    				}
    	printf("%d\n",ans);
    	return 0;
    }
    
  • 相关阅读:
    IDEA 的默认tomcat日志位置以及默认编译后的classes位置
    在linux环境下tomcat 指定 jdk或jre版本
    在Linux环境如何在不解压情况下搜索多个zip包中匹配的字符串内容
    说一下最近找的工作所遇到的一个巨坑,跟各位同行分享一下。(与技术无关)
    Jmeter 深入性能测试进阶-01
    英语
    python 01
    fiddler,ADB, Monkey
    http 协议,SSL证书,http头信息,tcp/http区别,支付功能测试
    扎马步-计算机网络和系统基础知识
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15439627.html
Copyright © 2020-2023  润新知