AtCoder Grand Contest 007
AtCoder Grand Contest 007
A - Shik and Stone
翻译
题解
傻逼玩意
#include<cstdio>
int n,m,tot;char ch[10];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
scanf("%s",ch+1);
for(int j=1;j<=m;++j)
tot+=ch[j]=='#';
}
puts(tot==n+m-1?"Possible":"Impossible");
return 0;
}
B - Construct Sequences
翻译
题解
诶,简单构造题我也不会做,真的是对于构造一窍不通。
我们让\(a\),\(b\)是两个等差数列,保证\(a_i+b_i\)相等,然后公差比\(n\)大就好,每次读进来一个\(p_i\),你就让对应的\(a\)减去一个\(n-i\)就好了。
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 20200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,a[MAX],b[MAX];
int main()
{
n=read();
for(int i=1;i<=n;++i)a[i]=i*(n+1),b[i]=(n-i+1)*(n+1);
for(int i=1;i<=n;++i)a[read()]-=(n-i+1);
for(int i=1;i<=n;++i)printf("%d ",a[i]);puts("");
for(int i=1;i<=n;++i)printf("%d ",b[i]);puts("");
}
C - Pushing Balls
翻译
数轴上有\(n\)个球和\(n+1\)个洞,每个球都在两个洞的中间,假设把所有东西放在一起,假设相邻两个物品的距离为\(d_i\),那么\(d_i-d_{i-1}=x\)。每次会等概率选择一个球,并且等概率选择它向左还是向右,它会一直朝着那个方向走,直到掉进坑里,如果这个洞里已经有球,它会从这个洞上面直接过去,继续移动。求所有合法方案中球移动的距离和的期望。一个合法方案是所有球都恰好进入了一个洞,并且只有一个洞没有球。
题解
神仙题,不会。DZYO的题解
官方题解:
在移动完一个球之后,重编号所有的洞和球,每个球仍然在两个洞之间。再重新计算期望意义下相邻的球和洞之间的距离,发现期望距离仍然是一个等差数列,然后从一号球开始顺次计算答案。
代码是照着打的。
#include<iostream>
#include<cstdio>
using namespace std;
double d,x,n,ans;
int main()
{
cin>>n>>d>>x;
for(int i=n;i;--i)
{
double sum=(d*2*n+n*(n+n-1)*x);
ans+=sum/2/n;
double dd=(d*(n+n-2)+d+2*x+3*d+3*x)/2/n;
sum-=(4*d+4*n*x-2*x)/2/n;--n;
d=dd;x=(sum-2*n*d)/n/(n+n-1);
}
printf("%.10lf\n",ans);
return 0;
}
D - Shik and Game
翻译
(什么傻吊题面)
有一个数轴,初始情况下玩家在\(0\)位置,出口在\(E\)位置,数轴上还有\(n\)只熊,你只要到了它的位置,再过\(T\)个单位时间它所在的位置就会出现一个金币。求从出发到捡完所有金币再到出口的最短时间。
题解
显然是把熊按照维护分成若干段,先访问过这一段的所有熊,再回到第一个熊,再顺次拿走所有金币。考虑一个暴力\(dp\),设\(f[i]\)表示当前到了\(i\)并且前面的金币都拿完的最短时间,然后得到式子\(f[i]=min(f[j]+max(t,2*(x[i]-x[j+1])))\),转移很显然。
发现走一段回去再走过来访问到每只熊的时间恰好是这段路程的两倍。意味着维护一下当且可以转移过来的位置,使得距离大于\(t\),那么它一定是一段前缀,那么记一下前缀最小值就完事了。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 100100
#define ll long long
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,E,T,x[MAX];
ll ans,f[MAX],mn=1e18;
int main()
{
n=read();E=read();T=read();
for(int i=1;i<=n;++i)x[i]=read();
memset(f,63,sizeof(f));f[0]=0;
for(int i=1,j=0;i<=n;++i)
{
for(;T<=(x[i]-x[j+1])<<1;++j)mn=min(mn,f[j]-2*x[j+1]);
if(j<i)f[i]=min(f[i],f[j]+T);
f[i]=min(f[i],mn+2*x[i]);
}
cout<<f[n]+E<<endl;
return 0;
}
E - Shik and Travel
翻译
给定一棵二叉树,每个节点的儿子数要么是\(2\)要么是\(0\)(除叶子节点外的所有点的度数都是\(2\))。现在你要访问所有叶子节点。要求从根节点出发,最后再回到根。每天你可以选择一个没有去过的叶子节点,然后走过去,花费就是路径上的权值之和。每条边都必须恰好被走过两次,总花费就是除了第一天从根节点出发以及最后一天回到根节点之外的每一天的花费的最大值。最小化这个最大值。
题解
最小化最大值,显然二分。现在考虑如何判定二分值是否合法。
因为每条边必须经过恰好两次,所以一旦进入了一棵子树,必定要走完所有其中所有叶子才能出去。
定义二元组\((a,b)\)表示进入到\(u\)的子树中的时候在子树内产生的花费是\(a\),离开子树那天,在子树内产生的贡献是\(b\)。合并答案的时候枚举两个儿子的所有二元组,不妨设左子树\(i\)是\((a,b)\),右子树\(j\)是\((c,d)\),首先会合并出一条新路径\(b+c+V_i+V_j\),判定是否合法(与二分值比较),如果合法的话,意味着我们可以合并一条路径\((a+V_i,d+V_j)\),调换左右儿子的顺序可以类似得到一个二元组\((c+V_j,b+V_i)\)。发现这样子每次向上维护这个集合内的元素即可维护出答案。然而这样子的状态增长太快,我们需要减少状态。比如说我们匹配出来的结果是\((a+V_i,d+V_j)\),那么我们并不在意\(b,c\)是什么,只需要他们合法就行了。那么对于每一个\(a\),我们能够匹配的\(d\)一定是越小越好。反过来相同。我们设节点\(u\)的二元组集合为\(S_u\),发现\(|S_u|\le 2*min(|S_i|,|S_j|)\)。我们可以选择元素个数较小的那一边,用它的第一维匹配元素较多的那一边的第二维。这样子总的状态数就被压成了\(O(nlgon)\)级别的,再加上二分的答案复杂度就是\(O(nlog(n)log(ans))\)。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define MAX 132000
#define ll long long
#define pi pair<ll,ll>
#define pb push_back
#define mp make_pair
#define fr first
#define sd second
#define vp vector<pi>
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next,w;}e[MAX];
int h[MAX],cnt=1;
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
int n;ll mid,mn[MAX];
vp f[MAX];
bool cmpx(pi a,pi b){return a.fr<b.fr;}
bool cmpy(pi a,pi b){return a.sd<b.sd;}
void Merge(vp &u,vp ls,vp rs)
{
if(ls.size()>rs.size())swap(ls,rs);
int t1=ls.size(),t2=rs.size();
if(!t1||!t2)return;
sort(ls.begin(),ls.end(),cmpy);
sort(rs.begin(),rs.end(),cmpx);
mn[0]=rs[0].sd;for(int i=1;i<t2;++i)mn[i]=min(mn[i-1],rs[i].sd);
for(int i=0,j=t2-1;i<t1;++i)
{
while(j>=0&&ls[i].sd+rs[j].fr>mid)--j;
if(j>=0)u.pb(mp(ls[i].fr,mn[j]));
}
sort(ls.begin(),ls.end(),cmpx);
sort(rs.begin(),rs.end(),cmpy);
mn[0]=rs[0].fr;for(int i=1;i<t2;++i)mn[i]=min(mn[i-1],rs[i].fr);
for(int i=0,j=t2-1;i<t1;++i)
{
while(j>=0&&ls[i].fr+rs[j].sd>mid)--j;
if(j>=0)u.pb(mp(mn[j],ls[i].sd));
}
}
void dfs(int u)
{
f[u].clear();if(!h[u]){f[u].pb(mp(0,0));return;}
for(int i=h[u];i;i=e[i].next)dfs(e[i].v);
for(int i=h[u];i;i=e[i].next)
for(int j=0,l=f[e[i].v].size();j<l;++j)
f[e[i].v][j].fr+=e[i].w,f[e[i].v][j].sd+=e[i].w;
if(h[u])Merge(f[u],f[e[h[u]].v],f[e[e[h[u]].next].v]);
}
int main()
{
n=read();
for(int i=2,a,v;i<=n;++i)a=read(),v=read(),Add(a,i,v);
ll l=0,r=1e9,ret=1e9;
while(l<=r)
{
mid=(l+r)>>1;dfs(1);
if(f[1].empty())l=mid+1;
else ret=mid,r=mid-1;
}
cout<<ret<<endl;
return 0;
}
F - Shik and Copying String
翻译
题解
大概是,你画个图,发现只需要这样子折一下就好了。那么答案就是最多的折的次数。说不清啊。看一下官方题解的图就好了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define MAX 1000010
int n,ans;
char s[MAX],t[MAX];
queue<int> Q;
int main()
{
scanf("%d",&n);scanf("%s",s+1);scanf("%s",t+1);
if(!strcmp(s+1,t+1)){puts("0");return 0;}
for(int i=n,p=n;i;--i)
{
if(t[i]==t[i-1])continue;
p=min(p,i);while(p&&s[p]!=t[i])--p;
if(!p){puts("-1");return 0;}
while(!Q.empty())
if((int)Q.front()-(int)Q.size()>=i)Q.pop();
else break;
Q.push(p);if(i^p)ans=max(ans,(int)Q.size());
}
printf("%d\n",ans+1);return 0;
}
AtCoder Grand Contest 007的更多相关文章
- AtCoder Grand Contest 007 E:Shik and Travel
题目传送门:https://agc007.contest.atcoder.jp/tasks/agc007_e 题目翻译 现在有一个二叉树,除了叶子每个结点都有两个儿子.这个二叉树一共有\(m\)个叶子 ...
- AtCoder Grand Contest 007题解
传送门 \(A\) 咕咕咕 //quming #include<bits/stdc++.h> #define R register #define fp(i,a,b) for(R int ...
- AtCoder Grand Contest 012
AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...
- AtCoder Grand Contest 011
AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...
- AtCoder Grand Contest 031 简要题解
AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...
- AtCoder Grand Contest 010
AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...
- AtCoder Grand Contest 009
AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...
- AtCoder Grand Contest 008
AtCoder Grand Contest 008 A - Simple Calculator 翻译 有一个计算器,上面有一个显示按钮和两个其他的按钮.初始时,计算器上显示的数字是\(x\),现在想把 ...
- AtCoder Grand Contest 006
AtCoder Grand Contest 006 吐槽 这套题要改个名字,叫神仙结论题大赛 A - Prefix and Suffix 翻译 给定两个串,求满足前缀是\(S\),后缀是\(T\),并 ...
随机推荐
- 【html】前端实现筛选条件跳转
之前与PHP的合作模式之一是前端这边负责写好静态页面交货. 那现在新进的公司,PHP说筛选由前端来实现. 嗯,好吧.实现就实现,多锻炼下咯. <div class="fliter&qu ...
- MB_SELECT_GR_BLOCKED_STOCK 读取物料收货冻结库存
MMBE 查询物料的当前库存,有一列是收货冻结库存(GR Blocked Stock),但是没有明细. 通过函数 MB_SELECT_GR_BLOCKED_STOCK 可以查询物料收货冻结库存的明细. ...
- # 2017-2018-2 20155231《网络对抗技术》实验九: Web安全基础实践
2017-2018-2 20155231<网络对抗技术>实验九: Web安全基础实践 实验要求: 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验内容: ( ...
- 20155318 《网络攻防》Exp2 后门原理与实践
20155318 <网络攻防>Exp2 后门原理与实践 基础问题回答 例举你能想到的一个后门进入到你系统中的可能方式? 下载软件前要勾选一些用户协议,其中部分就存在后门进入系统的安全隐患. ...
- Ueditor使用笔记
富文本编辑器在javaweb项目中还是比较常见的,如:ckeditor.kindeditor.ueditor等.今天主要叙述的对象为ueditor,它属于百度的.闲话不多说,下面开始介 ...
- python 回溯法 子集树模板 系列 —— 2、迷宫问题
问题 给定一个迷宫,入口已知.问是否有路径从入口到出口,若有则输出一条这样的路径.注意移动可以从上.下.左.右.上左.上右.下左.下右八个方向进行.迷宫输入0表示可走,输入1表示墙.为方便起见,用1将 ...
- linux查找进程pid并杀掉
命令:ps aux | grep `pwd` | grep -v grep | awk '{print $2}' | xargs kill -9 详细解释[我的有道云笔记,不知道为什么没法直接复制到 ...
- 小知识点--crontab
前言 这两周学了很多东西,还把golang语言基本掌握了,收获还是挺多的.在做安全的过程中,有很多需要定时执行的任务,比如抓取主机数量,端口数据等,这都逃不开linux中的crontab命令,今天分享 ...
- AHD/TVI/CVI/CVBS/IP
1.CVBS是最早的模拟摄像机,现在看来效果差. 2.AHD TVI CVI都是模拟摄像机的升级版,俗称同轴,三种名称只是用的方案系统不一样而已,相比模拟的效果清晰,和模拟的外观都是一样的bn ...
- 学习git 新手。这个写的不错
转自:https://www.cnblogs.com/wupeiqi/p/7295372.html 版本控制 说到版本控制,脑海里总会浮现大学毕业是写毕业论文的场景,你电脑上的毕业论文一定出现过这番景 ...