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. (转)matlab练习程序(HOG方向梯度直方图)

    matlab练习程序(HOG方向梯度直方图)http://www.cnblogs.com/tiandsp/archive/2013/05/24/3097503.html HOG(Histogram o ...

  2. 【洛谷 P1129】 [ZJOI2007]矩阵游戏 (二分图匹配)

    题目链接 看到题目肯定首先会想到搜索. 然鹅数据范围\(n<=200\)这么大(其实也不算太大),肯定是不行的. 如果\((i,j)\)是\(1\),从\(i\)向\(j\)连一条边,表示第\( ...

  3. Fire! (双bfs+预处理)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  4. kndo grid:通过checkbox 实现多选和全选

    在kendo grid 里要想通过checkbox 实现多选和权限,我们就要通过templeate 和input 标签对kendo grid 进行自定义 1. 在column 里面加入一列checkb ...

  5. nodewebkitV0.21.6版本的学习

    1.下载 https://nwjs.io/ 建议下载sdk版本,有调试功能,正式发布时,使用normal版本 下载以后解压,得到的文件目录如下 点击nw.exe,显示如下 2.hello world ...

  6. centos7系统安装配置

    下载centos7 iso镜像 电脑里面本来有ubuntu系统,直接在u盘做好启动盘安装即可,选择手动分区(忘了),将原本ubuntu系统分区压缩200G.系统不要选择最小化,选择gnome的图形界面 ...

  7. pam会话函数详解

    pam会话函数详解 http://www.xuebuyuan.com/2223069.html http://blog.itpub.net/15480802/viewspace-1406088/ ht ...

  8. python之operator操作符函数

    operator函数主要分为以下几类:对象比较.逻辑比较.算术运算和序列操作. 举例: #python 3.4 >>> operator.eq(1,2)False >>& ...

  9. yml格式

    是什么? yml文件扩展名是YAML的缩写,YAML于2001年出现,是一种数据描述语言,和xml类似 为什么用它? 我们在做javaweb项目的时候最常见的就是.xml配置文件和properitie ...

  10. lnmp的安装--mysql

    1.前期准备 创建组:groupadd mysql 创建用户:useradd -r -g mysql mysql 创建mysql文件夹于数据存放文件夹data mkdir -p /usr/www/my ...