Codeforces 1059

比赛链接

好失败啊。。

D挺简单的,但是没做。E读错题了,以为链可以拐弯,不知这样怎么求每个点最远延伸距离(想了想好像不难不过也好像很麻烦就弃疗了)。不然不就是个显然的贪心么。。

Update:E读错题了,读成NOIP Day1T3了。

A.Cashier

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1e5+7; int n,L,a,t[N],l[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
} int main()
{
n=read(), L=read(), a=read();
for(int i=1; i<=n; ++i) t[i]=read(),l[i]=read();
int ans=0, las=0; t[++n]=L;
for(int i=1; i<=n; ++i)
{
ans+=(t[i]-las)/a;
las=t[i]+l[i];
}
printf("%d\n",ans); return 0;
}

B.Forgery

#include <cstdio>
#include <cctype>
#define gc() getchar()
using namespace std;
const int N=1005,B=65;
const int dx[9]={-1,-1,-1,0,1,1,1,0};
const int dy[9]={-1,0,1,1,1,0,-1,-1}; int vis[N][N];
char s[N][N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
} int main()
{
int n=read(),m=read();
for(int i=1; i<=n; ++i) scanf("%s", s[i] + 1);
for(int i=2; i<n; ++i)
{
for(int j=2; j<m; j++)
{
bool flag=0;
for(int k=0; k<8; k++)
{
int xn=i+dx[k], yn=j+dy[k];
if(s[xn][yn] != '#')
{
flag=1;
break;
}
}
if(flag) continue;
for(int k=0; k<8; k++)
{
int xn=i+dx[k], yn=j+dy[k];
vis[xn][yn]=1;
}
}
}
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=m; j++)
{
if(s[i][j]=='#' && vis[i][j]!=1)
{
puts("NO");
return 0;
}
}
}
puts("YES");
return 0;
}

C.Sequence Transformation

//not mine...
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar() int Ans[1000005]; inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
} int main()
{
int n=read();
if(n==1) printf("1\n");
if(n==2) printf("1 2\n");
if(n==3) printf("1 1 3\n");
if(n<=3) return 0; int d=1, p1=2, p2=3, cnt=0; while(d!=n)
{
int tot=n/d;
if(tot-n/p1 < tot-n/p2)
{
for(int i=d; i<=n; i+=d)
if(i%p1) Ans[++cnt]=d;
d=p1;
}
else
{
for(int i=d; i<=n; i+=d)
if(i%p2) Ans[++cnt]=d;
d=p2;
}
p1=d<<1;
p2=3*d;
if(d==n) Ans[++cnt]=d;
if(cnt==n) break;
}
for(int i=1; i<=n; ++i) printf("%d ", Ans[i]); return 0;
}

比赛结束后

D.Nature Reserve(二分)

二分半径r。我们发现半径确定后,圆心的纵坐标也确定(在y=r上)。

这样我们要求是否存在圆心在y=r上的覆盖所有点的圆。对每个点画一个半径为r的圆,它们需要在y=r这条直线上有交。

每个圆到y=r的两个交点可以用勾股定理算出来,可以转成区间是否有交的问题。求最左的右端点和最右的左端点就行了。

因为要与x轴相切,所以半径可能非常大,用勾股定理可以得到最大是5e13+。因为范围较大注意简化运算减少误差。

//61ms	7700KB
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 200000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e6+6; int n,x[N],y[N];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
bool Check(double r)
{
double L=-1e18,R=1e18,tmp;
for(int i=1; i<=n; ++i)
{
if(r+r<y[i]) return 0;
tmp=sqrt(1.0*(r+r-y[i])*y[i]);
L=std::max(L,-tmp+x[i]), R=std::min(R,tmp+x[i]);
if(L>R) return 0;
}
return 1;
} int main()
{
n=read(); int cnt=0;
for(int i=1; i<=n; ++i) x[i]=read(),y[i]=read(),cnt+=(y[i]<0);
if(cnt)
{
if(cnt!=n) return puts("-1"),0;
for(int i=1; i<=n; ++i) y[i]=-y[i];
}
double l=0,r=1e14,mid;
for(int T=80; T--; )
{
// if(l>1 && l+1>r) mid=sqrt(l*r);//几何平均数该这么写么。。
// else mid=(l+r)*0.5;
if(Check(mid=(l+r)*0.5)) r=mid;
else l=mid;
}
printf("%.7lf\n",l); return 0;
}

E.Split the Tree(贪心 并查集/二分)

每条链只能向上覆盖,那贪心策略就显然了啊(子树每个点求最远能向上覆盖的距离)。

可以在DFS的过程中存下该链的信息,然后二分。也可以直接用并查集合并被覆盖的链。

//31ms	6200KB
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 200000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+6; int w[N],fa[N],F[N],q[N],dgr[N],dep[N];
LL sum[N];
bool vis[N];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline LL readll()
{
LL now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
int Find(int x)
{
return x==F[x]?x:F[x]=Find(F[x]);
} int main()
{
int n=read(),L=read(); LL S=readll();
for(int i=1; i<=n; ++i) if((w[i]=read())>S) return puts("-1"),0;
for(int i=2; i<=n; ++i) ++dgr[fa[i]=read()];
for(int i=1; i<=n; ++i) F[i]=i,sum[i]=sum[fa[i]]+w[i],dep[i]=dep[fa[i]]+1; int h=0,t=0,Ans=0;
for(int i=1; i<=n; ++i) if(!dgr[i]) q[t++]=i;
while(h<t)
{
int x=q[h++];
if(vis[x]) continue;
++Ans; int num=0; LL s=0;
while(x)
{
int nxt=Find(x);
num+=dep[x]-dep[nxt]+1, s+=sum[x]-sum[nxt]+w[nxt];
if(num>L||s>S) break; vis[nxt]=1;
if(!--dgr[fa[nxt]]) q[t++]=fa[nxt];
F[nxt]=Find(fa[F[nxt]]), x=fa[nxt];
}
}
printf("%d\n",Ans); return 0;
}

Codeforces Round #514 (Div. 2)的更多相关文章

  1. Codeforces Round #514 (Div. 2) D. Nature Reserve

    http://codeforces.com/contest/1059/problem/D 最大值: 最左下方和最右下方分别有一个点 r^2 - (r-1)^2 = (10^7)^2 maxr<0 ...

  2. Codeforces Round #514 (Div. 2) E. Split the Tree(倍增+贪心)

    https://codeforces.com/contest/1059/problem/E 题意 给出一棵树,每个点都有一个权值,要求你找出最少条链,保证每个点都属于一条链,而且每条链不超过L个点 和 ...

  3. Codeforces Round #514 (Div. 2):D. Nature Reserve(二分+数学)

    D. Nature Reserve 题目链接:https://codeforces.com/contest/1059/problem/D 题意: 在二维坐标平面上给出n个数的点,现在要求一个圆,能够容 ...

  4. Codeforces Round #514 (Div. 2) C. Sequence Transformation(递归)

    C. Sequence Transformation 题目链接:https://codeforces.com/contest/1059/problem/C 题意: 现在有1~n共n个数,然后执行下面操 ...

  5. Codeforces Round #514 (Div. 2) C. Sequence Transformation 思维构造

    题意 给出一个1-n的集合   gcd 集合里面的所有数  得到的 一个 数   然后自己选择删去一个数   要使得到的数 构成的数列 的字典序最大 思路: gcd所有数 那gcd得到的数肯定要小于数 ...

  6. Codeforces Round #514 (Div. 2) B - Forgery

    这个题我一开始没思路,最后也没思路 2个小时一直没思路 本来还想解释题意的,写了半天发现解释的不是很清楚,你还是google翻译一下吧 这个题解法是这样的: 首先,给你图案里面有很多的点,每个点的周围 ...

  7. Codeforces Round #514 (Div. 2) C. Sequence Transformation

    题目大意:给你一个n 从1,2,3......n这个序列中 依次进行以下操作:1 .求所有数的最大公因数,放入a序列里面 2 .任意删去一个元素 一直到序列为空 根据删除元素的不同,导致序列a的字典序 ...

  8. Codeforces Round#514 Div.2 翻车记

    A:签到 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  9. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

随机推荐

  1. ES系列八、正排索Doc Values和Field Data

    1.Doc Values 聚合使用一个叫Doc Values的数据结构.Doc Values使聚合更快.更高效且内存友好. Doc Values的存在是因为倒排索引只对某些操作是高效的.倒排索引的优势 ...

  2. Json对象和字符串互相转换 数据拼接 JSON使用方式

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 一.JSON字符串转换为JSON对象: eval() 和 JSON.parse eg- json字符串: ...

  3. Ex 6_16 旧货销售问题_第七次作业

    即可 子问题定义:定义数组B(S,j),其中 B(S,j)表示在子集S中结束位置为j的子问题的最大收益值,其中j的前一个地点有两种情况,第一种情况是某个拍卖会 另一种情况是从家里出发. 递归关系: 初 ...

  4. [学习笔记]Javascript可选的分号

    1.前言 由于Javascript有自动识别一句语句的结尾,但是缺少必要分号作为结尾符,会降低代码的可读性和整洁性.通过javascript权威指南By淘宝前端团队译,这分号还算比较好玩的. 2.样例 ...

  5. Day5----------------------文件合并与文件归档

    一.文件合并 1.命令: >:覆盖式 >>:追加式 例如:cat /etc/passwd > a.txt      把/etc/passwd下的内容合并到a.txt内,若没有文 ...

  6. pytest四:fixture_yield 实现 teardown

    既然有 setup 那就有 teardown,fixture 里面的 teardown 用 yield 来唤醒 teardown的执行 在所有用例执行完后执行:yield import pytest ...

  7. Java列表、数组、字符串

    列表(list) list中添加,获取,删除元素 添加方法是:.add(e): 获取方法是:.get(index): 删除方法是:.remove(index), 按照索引删除: .remove(Obj ...

  8. 《剑指offer》-青蛙跳台阶II

    一只青蛙一次可以跳上1级台阶,也可以跳上2级--它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 其实题目很水...就是一个等比数列通项公式嘛 f(0)=1 f(1)=1 f(n)=f( ...

  9. 【C++ Primer | 19】嵌套类、局部类

    嵌套类 #include <iostream> using namespace std; class c1 { public: int a; void foo(); class c2 { ...

  10. Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)

    今天在对 Ubuntu 进行更新源的时候,突然出现下列错误(为了省事,更新前直接切换了 root 用户) 上网查了一下,网上解释说应该是之前那个更新被强制取消的问题,进程仍然还在.用这个命令查看一下: ...