AGC004(A~E)
前言
FFF不會做,正解好神仙,爬了
正題
AT2041 [AGC004A] Divide a Cuboid
https://www.luogu.com.cn/problem/AT2041
題目大意
一個A?B?CA*B*CA?B?C的立方體,分成兩個長方體使得邊長都是整數而且體積差最小。
1≤A,B,C≤1091\leq A,B,C\leq 10^91≤A,B,C≤109
解題思路
如果有一邊是偶數之間這邊開始分,不然就找一邊分的最小就好了。
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
題目大意
nnn個顏色的史萊姆,第iii只可以花費aia_iai?獲得,或者花費kkk使得所有獲得的史萊姆顏色加一后模nnn,求最少花費多少能獲得所有顏色的史萊姆。
1≤n≤2000,1≤ai,k≤1091\leq n\leq 2000,1\leq a_i,k\leq 10^91≤n≤2000,1≤ai?,k≤109
解題思路
顯然我們可以通過控制獲得的順序使得加一的次數就是次數最多的那個史萊姆,所以處理出最多加iii次的情況下每個史萊姆的最少獲得費用。
然后枚舉就好了。時間復雜度:O(n2)O(n^2)O(n2)。
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×mn\times mn×m的網格圖,滿足四邊上都沒有’#’,現在要求求出兩個n×mn\times mn×m的網格圖使得上面的’#‘四聯通且兩張圖上’#'的并恰好是給出的網格圖。
1≤n,m≤5001\leq n,m\leq 5001≤n,m≤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
題目大意
給出nnn個點的一棵基環外向樹,保證一號點在環上,每次可以修改一個點的父親(可以是自己),求最少修改次使得所有點的kkk級祖先都是111號點。
1≤n≤105,1≤k≤1091\leq n\leq 10^5,1\leq k\leq 10^91≤n≤105,1≤k≤109
解題思路
顯然一號點一定要連自己,因為環上必然只有一個點滿足kkk級祖先是111,所以改其他節點還不如改一號點。
然后問題就變成樹上的了,之間貪心到必須改的時候再改就好了。
時間復雜度:O(n)O(n)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×mn\times mn×m的網格上有一些機器人和一個出口,每次你可以讓所有的機器人上/左/下/右移動,出界的機器人算為死亡,到達出口的機器人算為出逃,求最多能救走多少個機器人。
1≤n,m≤1001\leq n,m\leq 1001≤n,m≤100
解題思路
設fu,d,l,rf_{u,d,l,r}fu,d,l,r?表示所有機器人最多往上/下/左/右走了u/d/l/ru/d/l/ru/d/l/r步時最多能救多少機器人,然后暴力轉移即可。
時間復雜度:O(n4)O(n^4)O(n4)
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; }總結
以上是生活随笔為你收集整理的AGC004(A~E)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安标化申报(安标化备案)
- 下一篇: linux修改文件的权限命令(linux