Link:

AGC004 传送门

A:

……

#include <bits/stdc++.h>

using namespace std;
long long a,b,c;
int main()
{
scanf("%lld%lld%lld",&a,&b,&c);
if(a%==||b%==||c%==) puts("");
else printf("%lld",min(a*b,min(a*c,b*c)));
return ;
}

Problem A

B:

从0到$n-1$枚举$k$

对于每一个$k$,$res=k*x+\sum_{i=1}^n min(dat[i-1],dat[i-2],..dat[i-k])$

接下来对于每个$i$预处理出$pre[i][j]$表示第$i$个数及其之前$j$个数中的最小值

这样就能在$O(n)$内算出每个$k$时的结果

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN=;
ll x,res=1e15;
int n,pre[MAXN][MAXN]; int main()
{
scanf("%d%lld",&n,&x);
for(int i=;i<n;i++) scanf("%d",&pre[i][]);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
{
int cur=(i-j+n)%n;
pre[i][j]=min(pre[i][j-],pre[cur][]);
} for(int i=;i<n;i++)
{
ll t=i*x;
for(int j=;j<n;j++) t+=pre[j][i];
res=min(res,t);
}
printf("%lld",res);
return ;
}

Problem B

C:

纯构造题

虽然算是奇技淫巧,但还是有些规律可循的……

一个条件:边界上没有紫色的部分

这其实就暗示我们要根据这个条件构造连通性,两颜色各占一条边

接下来可以先让两种颜色完全没有重叠,再对应有重叠的部分特殊处理:

1、奇数行(不含边界)为蓝色,偶数行为红色

2、将紫色部分补成两种颜色

这样就既保证只有紫色部分有两种颜色,有保证两种颜色分别连通了!

官方题解的例子:

#include <bits/stdc++.h>

using namespace std;
const int MAXN=;
int n,m;
char a[MAXN][MAXN],b[MAXN][MAXN],dat[MAXN][MAXN];
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%s",dat[i]+);
for(int i=;i<=n;i++)
{
a[i][]=b[i][m]='#';
if(i&) for(int j=;j<=m-;j++) a[i][j]='#';
else for(int j=;j<=m-;j++) b[i][j]='#';
} for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
a[i][j]=(dat[i][j]!='#'&&a[i][j]!='#')?'.':'#',
b[i][j]=(dat[i][j]!='#'&&b[i][j]!='#')?'.':'#';
for(int i=;i<=n;i++) printf("%s\n",a[i]+);
puts("");
for(int i=;i<=n;i++) printf("%s\n",b[i]+);
return ;
}

Problem C

感觉构造题还是有一些通用思想的

对于此题,就利用了弱化条件的思想

(1)先不考虑有部分要重叠,只保证无重叠且各自连通

(2)再考虑怎么保证任意添加都不影响连通性

D:

首先能比较简单得证出1必须为自环(否则包含1的环中的其他点一定不满足要求)

此时$n$个点,$n-1$条边形成一棵树,

于是将问题转化为将一棵树切割成高度不大于$k-1$的子树的最小值

(特判:子树的根为1时高度不大于$k$即可)

这样从叶子节点向上贪心选取即可(一定不能从上向下贪心!)

#include <bits/stdc++.h>

using namespace std;
const int MAXN=1e5+;
vector<int> G[MAXN];
int n,k,dat[MAXN],dp[MAXN],res=; void dfs(int x)//要从叶子节点开始推!
{
for(int i=;i<G[x].size();i++)
if(G[x][i]!=dat[x]) dfs(G[x][i]);
if(++dp[x]>=k&&dat[x]!=) res++,dp[x]=;
dp[dat[x]]=max(dp[dat[x]],dp[x]);
} int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) scanf("%d",&dat[i]);
if(dat[]!=) res++,dat[]=;
for(int i=;i<=n;i++) G[dat[i]].push_back(i); dfs();printf("%d",res);
return ;
}

Problem D

一般树上递推/贪心都要从叶子节点向上推

从上往下直接贪心一般都有问题

E:

把所有机器人的移动看成出口的移动

这样出口每向一个方向移动一格会ban掉相反方向的一整行/列

而产生的贡献的长度由其向垂直的两个方向移动的距离及产生的限制限定

这样设$dp[u][d][l][r]$表示出口已向四个方向移动$u,d,l,r$后的最值,加个前缀和$O(1)$算贡献即可

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=;
char s[MAXN][MAXN];
int n,m,x,y;
short dp[MAXN][MAXN][MAXN][MAXN];
short line[MAXN][MAXN],col[MAXN][MAXN];
void upd(short &a,short b){a=max(a,b);} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%s",s[i]+);
for(int j=;j<=m;j++)
{
if(s[i][j]=='E') x=i,y=j;
line[i][j]=line[i][j-]+(s[i][j]=='o');
col[i][j]=col[i-][j]+(s[i][j]=='o');
}
} short res=;
dp[][][][]=;
for(int u=;u<x;u++) for(int d=;d<=n-x;d++)
for(int l=;l<y;l++) for(int r=;r<=m-y;r++)
{
if(!(u+d<max(x,n-x+)&&l+r<max(y,m-y+))) continue;
short &cur=dp[u][d][l][r];res=max(res,cur);
int L=max(r+,y-l),R=min(y+r,m-l),D=min(x+d,n-u),U=max(x-u,d+);
if(u++d<x) upd(dp[u+][d][l][r],cur+line[x-u-][R]-line[x-u-][L-]);
if(d++u<=n-x) upd(dp[u][d+][l][r],cur+line[x+d+][R]-line[x+d+][L-]);
if(l++r<y) upd(dp[u][d][l+][r],cur+col[D][y-l-]-col[U-][y-l-]);
if(r++l<=m-y) upd(dp[u][d][l][r+],cur+col[D][y+r+]-col[U-][y+r+]);
}
printf("%d",res);
return ;
}

Problem E

F:

$Atcoder$风格神仙题,第一步就想不到系列……

树的情况:

(不能随便找一个点为根贪心,如果要贪心需要枚举所有点为根)

一般此类相邻点同时操作想到黑白染色

一棵树必然能黑白染色,每次操作就是将两点颜色取反,目标是所有点皆呈反颜色

由于能翻转的条件是必须要一黑一白,那么就能看成黑点的移动,移动一步就要翻转一次

接下来对每条边计算贡献,考虑儿子的子树中黑白点的差$s[i]$,贡献则为$abs(\sum s[i])$

如果总的黑白点数不等则无解

奇环的情况

由于非树边连接的点同颜色,每次操作相当于同时增加/减少2个黑点

因此只有在黑白点差为偶数时有解,此时将$x,y$到根路径上点的$s[i]$修改后再同样计算即可

偶环的情况

非树边连接的点颜色不同,每次操作相当于移黑点,关键在于确定转移数量

设$x,y$到根路径上的点分别为$a_i,b_i$,$x$向$y$转移了$k$

则要求$min{\sum |a_i-k|+|b_i+k|+|k|}$

此式的几何意义就是$a_i,-b_i,0$到$k$的距离和,明显最优$k$就是中位数,同样修改计算

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+;
struct edge{int nxt,to;}e[MAXN<<];
ll res=;
int lca,dep[MAXN],sum[MAXN],f[MAXN];
int n,m,fx,fy,head[MAXN],x,y,tot,TOT,cnt,t[MAXN]; void add_edge(int x,int y)
{
e[++TOT]=(edge){head[x],y};head[x]=TOT;
e[++TOT]=(edge){head[y],x};head[y]=TOT;
}
void dfs(int x,int anc,int val)
{
sum[x]=val;tot+=val;
dep[x]=dep[anc]+;f[x]=anc;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=anc)
{
if(dep[e[i].to])
{fx=x;fy=e[i].to;continue;}
dfs(e[i].to,x,-val),sum[x]+=sum[e[i].to];
}
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
int t=dep[x]-dep[y];
for(int i=;i<=t;i++) x=f[x];
while(x!=y) x=f[x],y=f[y];
return x;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d",&x,&y),add_edge(x,y);
dfs(,,); if(m==n-)
{
if(tot) return puts("-1"),;
for(int i=;i<=n;i++) res+=abs(sum[i]);
}
else if((dep[fx]-dep[fy])%==)
{
if(tot%) return puts("-1"),;
lca=LCA(fx,fy);tot=-tot/;res+=abs(tot); for(int k=fx;k;k=f[k]) sum[k]+=tot;
for(int k=fy;k;k=f[k]) sum[k]+=tot;
for(int i=;i<=n;i++) res+=abs(sum[i]);
}
else
{
if(tot) return puts("-1"),;
lca=LCA(fx,fy);
for(int k=fx;k!=lca;k=f[k])
t[++cnt]=sum[k],dep[k]=-;
for(int k=fy;k!=lca;k=f[k])
t[++cnt]=-sum[k],dep[k]=-;
t[++cnt]=;
sort(t+,t+cnt+);int val=t[cnt/]; for(int i=;i<=n;i++)
if(~dep[i]) res+=abs(sum[i]);
for(int i=;i<=cnt;i++)
res+=abs(t[i]-val);
}
printf("%d",res);
return ;
}

Problem F

[Atcoder Grand Contest 004] Tutorial的更多相关文章

  1. AtCoder Grand Contest 004

    AtCoder Grand Contest 004 A - Divide a Cuboid 翻译 给定一个\(A*B*C\)的立方体,现在要把它分成两个立方体,求出他们的最小体积差. 题解 如果有一条 ...

  2. AtCoder Grand Contest 004 C:AND Grid

    题目传送门:https://agc004.contest.atcoder.jp/tasks/agc004_c 题目翻译 给你一张网格图,指定的格子是紫色的,要求你构造出两张网格图,其中一张你可以构造一 ...

  3. AtCoder Grand Contest 004 C - AND Grid

    题意: 给出一张有紫色点的网格,构造一张红点网格和一张蓝点网格,使红蓝点的交集为紫色点. 保证网格四周没有紫色点. 构造一下,使蓝点和红点能够到每个点. #include<bits/stdc++ ...

  4. [Atcoder Grand Contest 003] Tutorial

    Link: AGC003 传送门 A: 判断如果一个方向有,其相反方向有没有即可 #include <bits/stdc++.h> using namespace std; ]; map& ...

  5. [Atcoder Grand Contest 002] Tutorial

    Link: AGC002 传送门 A: …… #include <bits/stdc++.h> using namespace std; int a,b; int main() { sca ...

  6. [Atcoder Grand Contest 001] Tutorial

    Link: AGC001 传送门 A: …… #include <bits/stdc++.h> using namespace std; ; ]; int main() { scanf(& ...

  7. AtCoder Grand Contest 004题解

    传送门 \(A\) 咕咕 int a,b,c; int main(){ scanf("%d%d%d",&a,&b,&c); if((a&1^1)|( ...

  8. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  9. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

随机推荐

  1. 【CodeForces】582 C. Superior Periodic Subarrays

    [题目]C. Superior Periodic Subarrays [题意]给定循环节长度为n的无限循环数列,定义(l,s)表示起点为l的长度为s的子串,(l,s)合法要求将子串从该起点开始以s为循 ...

  2. 2009 Round2 A Crazy Rows (模拟)

    Problem You are given an N x N matrix with 0 and 1 values. You can swap any two adjacent rows of the ...

  3. Python 开发中easy_install的安装及使用

    easy_install是一个python的扩展包,主要是用来简化python安装第三方安装包,在安装了easy_install之后,安装python第三方安装包就只需要在命令行中输入:easy_in ...

  4. H题 hdu 2520 我是菜鸟,我怕谁

    题目大意:http://acm.hdu.edu.cn/showproblem.php?pid=2520 我是菜鸟,我怕谁 Time Limit: 2000/1000 MS (Java/Others)  ...

  5. 《Applying Deep Learning to Answer Selection: A Study And an Open Task》文章理解小结

    本篇论文是2015年的IBM watson团队的. 论文地址: 这是一篇关于QA问题的一篇论文: 相关论文讲解1.https://www.jianshu.com/p/48024e9f7bb22.htt ...

  6. Caffe学习笔记3

    Caffe学习笔记3 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和h ...

  7. vue路由-动态路由和嵌套路由

    一.动态路由 我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件.例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染.那么,我们可以在 vue-route ...

  8. V4L2(二)虚拟摄像头驱动vivi深入分析【转】

    转自:http://www.cnblogs.com/tureno/articles/6694463.html 转载于: http://blog.csdn.net/lizuobin2/article/d ...

  9. python基础===python基础知识问答(转)

    1.到底什么是Python?你可以在回答中与其他技术进行对比 Python是一种解释型语言.与C语言和C的衍生语言不同,Python代码在运行之前不需要编译.其他解释型语言还包括PHP和Ruby. P ...

  10. 网络知识===wireshark抓包出现“TCP segment of a reassembled PDU”的解释(载)

    网上胡说八道,众说风云,感觉这篇还算靠谱点. 原文链接:http://blog.csdn.net/dog250/article/details/51809566 为什么大家看到这个以后总是会往MSS, ...