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\),并 ...
随机推荐
- mysql数据库怎么存入emoji表情,更改utf8mb4后为什么出现全是问号
在项目中遇到有人存emoji表情,出现如下错误: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x92\x94' for colum ...
- spring boot项目配置RestTemplate超时时长
配置类: @Configuration public class FeignConfiguration { @Bean(name="remoteRestTemplate") pub ...
- Java面试题,Java三大特性之一——多态的理解
首先我们知道Java是一门面向对象的语言 面向对象三大特性,封装.继承.多态. 封装.继承.多态 ↓ 无论是学习路线,还是众人的口语习惯,都是按照这个这样进行排序,这是有原因的.因为封装好了才能继承, ...
- 大数据入门第二十二天——spark(二)RDD算子(2)与spark其它特性
一.JdbcRDD与关系型数据库交互 虽然略显鸡肋,但这里还是记录一下(点开JdbcRDD可以看到限制比较死,基本是鸡肋.但好在我们可以通过自定义的JdbcRDD来帮助我们完成与关系型数据库的交互.这 ...
- sql查询语句示例
今天没事又专门学习了一下sql查询语句,个人感觉太重要了,于是就找了网上的一个示例自己练了起来,感觉学到了很多,下面跟大家分享一下sql查询语句的示例操作. 首先,我建了5张表,分别如下: (a)学生 ...
- HTML基础之JS
HTML中的三把利器的JS 又称为JavaScript,看着好像和Java有点联系,实际上他和java半毛钱关系都没有,JavaScript和我们学习的Python.Go.Java.C++等,都是一种 ...
- c语言数字图像处理(一):bmp图片格式及灰度图片转换
本篇文章首先介绍了bmp图片格式,主要参考wiki上的内容,包括bmp文件的存储方式,对于一些常见的bmp文件格式都给了例子,并且对8位 16位RGB555 16位RGB565格式的bmp文件进行了简 ...
- 173. Insertion Sort List【LintCode by java】
Description Sort a linked list using insertion sort. Example Given 1->3->2->0->null, ret ...
- 镜像仓库管理:与Portus不得不说的那些事
背景: 目前在做一个云计算相关的项目,其中有这样一个需求:每个平台用户都有自己的docker镜像仓库(docker registry),用户可以对自己的镜像仓库的push/pull权限进行管理,也就是 ...
- 炸弹人的Alpha版使用说明
本游戏是一款手机游戏,学生可以在无聊时打发时间,放松心情.现在只有三关,但游戏运行还算可以. 注意事项: 目前游戏还有一些不好的地方,游戏无法暂停,如果游戏任务死亡,则无法重开. 游戏后面的关卡还需要 ...