cf Round 613
A.Peter and Snow Blower(计算几何)
给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积。
保证这个点不在多边形内。
画个图能明白 这个图形是一个圆环,那么就是这个点距离多边形边缘最远的距离形成的圆面积减去这个点距离多边形边缘最近的距离形成的圆面积。
我们可以得出距离最远的点一定是多边形的顶点。
而距离最近的点不一定是多边形的顶点,但是在多边形的边上。
我们用勾股定理判断点与每条边形成的三角形的两边角。
如果有一个边角是钝角,则表示距离最近的点是顶点。
如果都是锐角,则表示距离最近的点在底边上。
我们用海伦公式求出三角形的面积,再除以底边*2,那么就得出了这个三角形的高。
此题得解。
# include <stdio.h> # include <string.h> # include <stdlib.h> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <math.h> # include <algorithm> using namespace std; # define lowbit(x) ((x)&(-x)) # define pi acos(-1.0) # define MAXN 100005 # define eps 1e-5 # define MAXM 1000005 # define MOD 1000000007 # define INF 1000000000 # define mem(a,b) memset(a,b,sizeof(a)) # define FOR(i,a,n) for(int i=a; i<=n; ++i) # define FO(i,a,n) for(int i=a; i<n; ++i) # define bug puts("H"); # define lch p<<1,l,mid # define rch p<<1|1,mid+1,r # pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long LL; typedef unsigned long long ULL; int _MAX(int a, int b){return a>b?a:b;} int _MIN(int a, int b){return a>b?b:a;} int Scan() {int res=0, flag=0;char ch;if((ch=getchar())=='-') flag=1;else if(ch>='0'&&ch<='9') res=ch-'0';while((ch=getchar())>='0'&&ch<='9') res=res*10+(ch-'0');return flag?-res:res; } void Out(int a) {if(a<0) {putchar('-'); a=-a;}if(a>=10) Out(a/10);putchar(a%10+'0'); }LL a[100005][2]; LL dis(LL x1, LL y1, LL x2, LL y2) {return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1); } int main () {LL n, px, py, ma=0;double mi=1e16;scanf("%lld%lld%lld",&n,&px,&py);FOR(i,1,n) {scanf("%lld%lld",&a[i][0],&a[i][1]);LL d = dis(a[i][0],a[i][1],px,py);mi=min(mi,(double)d); ma=max(ma,d);}a[n+1][0]=a[1][0], a[n+1][1]=a[1][1];FOR(i,1,n) {LL A2=dis(px,py,a[i][0],a[i][1]);LL B2=dis(px,py,a[i+1][0],a[i+1][1]);LL C2=dis(a[i][0],a[i][1],a[i+1][0],a[i+1][1]);double A=sqrt(A2), B=sqrt(B2), C=sqrt(C2);if (C2+B2>A2&&C2+A2>B2) {double P=(A+B+C)/2;double S=sqrt(P*(P-A)*(P-B)*(P-C));double H=S/C*2;mi=min(mi,H*H);}}printf("%.10lf\n",pi*(ma-mi));return 0; }
View Code
B.Skills(贪心+枚举+二分)
给你n个数,可以花费1使得数字+1,最大加到A,最多花费m。最后,n个数里的最小值为min,为A的有k个,给你cm和cf,求force=min*cm+k*cf 的最大值,和n个数操作后的结果。
我们如果要让最小值增加,那它加到和第二小的一样时,就有两个最小值,接下来就要两个一起增加。到后来就要好多个一起增加了。
那么我们可以枚举加到A的有多少个,然后用二分的方法求剩下m元,可以使最小值最大为多少。
#include<bits/stdc++.h> #define N 100005 #define ll long long using namespace std;struct data {ll id,v; } a[N];bool cmp(data a,data b) {return a.v<b.v||a.v==b.v&&a.id<b.id; }ll n,A,cf,cm,m; ll L,ans[N],f,ansA,ansL; ll s[N];ll findL(ll m,ll R)//还剩多少m,右端点是什么 {ll l=0,r=A,ans=0;//二分确定最小值的值while(l<=r){ll mid=(r+l)>>1;//二分确定有多少个比这个值小,然后计算需要的花费int p=lower_bound(a+1,a+1+n,(data){0,mid},cmp)-a-1;if(p>R)p=R;if(p*mid-s[p]<=m){ans=mid;l=mid+1;}elser=mid-1;}return ans; } int main() {scanf("%lld%lld%lld%lld%lld",&n,&A,&cf,&cm,&m);for(int i=1; i<=n; i++){scanf("%lld",&a[i].v);a[i].id=i;}sort(a+1,a+n+1,cmp);//先排序再求前缀和for(int i=1; i<=n; i++)s[i]=s[i-1]+a[i].v;for(int i=0; i<=n; i++) //如果有i个设置为A的话 {ll p=A*i-s[n]+s[n-i];//花费if(p<=m){L=findL(m-p,n-i);//那最小值可以达到多少if(cm*L+cf*i>f) //更新答案 {f=cm*L+cf*i;ansA=i;//储存有几个变成AansL=L;//储存最小值要达到多少 }}}printf("%lld\n",f);for(int j=1; j<=n; j++){if(j>n-ansA)ans[a[j].id]=A;else if(a[j].v<=ansL)ans[a[j].id]=ansL;elseans[a[j].id]=a[j].v;}for(int i=1; i<=n; i++)printf("%lld ",ans[i]);return 0; }
View Code
C.Necklace(构造)
给你n种字符,每种有ai个,构造一个环,要求刨开环之后形成回文串,且种数最多。
显然当ai中有两个奇数,答案为0.
我们可以把这n个字符分成x个部分,且每个部分中每个字符的个数一样。
这样x<=gcd(a1,a2...ai).
我们证明答案一定能取到gcd(a1,a2...ai).
首先如果ai中有一个奇数,我们可以令每个部分都形成一个回文串。
如果ai中没有奇数,我们可以令每个部分与相邻的部分成为一个回文串。可以证明第一个部分
同样可以与最后一个部分成为回文串。
所以答案就是x
# include <stdio.h> # include <string.h> # include <stdlib.h> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <math.h> # include <algorithm> using namespace std; # define lowbit(x) ((x)&(-x)) # define pi acos(-1.0) # define MAXN 100005 # define eps 1e-5 # define MAXM 1000005 # define MOD 1000000007 # define INF 1000000000 # define mem(a,b) memset(a,b,sizeof(a)) # define FOR(i,a,n) for(int i=a; i<=n; ++i) # define FO(i,a,n) for(int i=a; i<n; ++i) # define bug puts("H"); # define lch p<<1,l,mid # define rch p<<1|1,mid+1,r # pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long LL; typedef unsigned long long ULL; int _MAX(int a, int b){return a>b?a:b;} int _MIN(int a, int b){return a>b?b:a;} int Scan() {int res=0, flag=0;char ch;if((ch=getchar())=='-') flag=1;else if(ch>='0'&&ch<='9') res=ch-'0';while((ch=getchar())>='0'&&ch<='9') res=res*10+(ch-'0');return flag?-res:res; } void Out(int a) {if(a<0) {putchar('-'); a=-a;}if(a>=10) Out(a/10);putchar(a%10+'0'); }int a[30];int gcd(int x, int y){y==0?x:gcd(y,x%y);} int main () {int n, cnt=0;scanf("%d",&n);FOR(i,1,n) scanf("%d",a+i), cnt+=a[i]&1;int G=a[1];FOR(i,2,n) G=gcd(G,a[i]);if (n==1) {printf("%d\n",a[1]);FOR(i,1,a[1]) putchar('a');putchar('\n');return 0;}if (cnt>=2) {puts("0");FOR(i,1,n) FOR(j,1,a[i]) putchar('a'+i-1);putchar('\n');}else if (cnt==1) {printf("%d\n",G);FOR(k,1,G) {FOR(i,1,n) if (a[i]%2==0) FOR(j,1,a[i]/G/2) putchar('a'+i-1);FOR(i,1,n) if (a[i]&1) FOR(j,1,a[i]/G) putchar('a'+i-1);for (int i=n; i>=1; --i) if (a[i]%2==0) FOR(j,1,a[i]/G/2) putchar('a'+i-1);}}else {printf("%d\n",G);FOR(k,1,G/2) {FOR(i,1,n) FOR(j,1,a[i]/G) putchar('a'+i-1);for (int i=n; i>=1; --i) FOR(j,1,a[i]/G) putchar('a'+i-1);}putchar('\n');}return 0; }
View Code
D.Kingdom and its Cities(虚树)
题意:给出n个节点的树,询问q次,每次询问mi个点,问将这mi个点分离开来
至少需要割掉多少个点。
(n<=1e5,sigma(mi)<=1e5)
显然无解的情况是存在两个点相邻。
我们先来考虑每次询问。从树的底层往高层看,
如果一个节点是询问点,那么它的子树中有询问点的就删掉它的子树。
如果一个节点是非询问点,那么它的有询问点的子树超过1个的时候,
就需要把这个节点为根的树给删了。
所以一遍dfs即可。复杂度O(n).对于q个询问,复杂度O(n*q).
因为sigma(mi)<=1e5.
我们把询问点单独拉出来建立一颗虚树。
复杂度O((n+sigma(m))*logn).
# include <stdio.h> # include <string.h> # include <stdlib.h> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <math.h> # include <algorithm> using namespace std; # define lowbit(x) ((x)&(-x)) # define pi acos(-1.0) # define MAXN 100005 # define eps 1e-5 # define MAXM 500001 # define MOD 1000000007 # define INF 1000000000 # define mem(a,b) memset(a,b,sizeof(a)) # define FOR(i,a,n) for(int i=a; i<=n; ++i) # define FO(i,a,n) for(int i=a; i<n; ++i) # define bug puts("H"); typedef long long LL; typedef unsigned long long ULL; int _MAX(int a, int b){return a>b?a:b;} int _MIN(int a, int b){return a>b?b:a;} int Scan() {int res=0, flag=0;char ch;if((ch=getchar())=='-') flag=1;else if(ch>='0'&&ch<='9') res=ch-'0';while((ch=getchar())>='0'&&ch<='9') res=res*10+(ch-'0');return flag?-res:res; } void Out(int a) {if(a<0) {putchar('-'); a=-a;}if(a>=10) Out(a/10);putchar(a%10+'0'); }struct Edge{int p, next;}edge[MAXN<<1]; int head[MAXN], cnt=1, mark, top, ans; int bin[20], dep[MAXN], id[MAXN], fa[MAXN][20], h[MAXN], st[MAXN], vis[MAXN];bool comp(int a, int b){return id[a]<id[b];} void bin_init(){bin[0]=1; FO(i,1,20) bin[i]=bin[i-1]<<1;} void add_edge(int u, int v) {if (u==v) return ;edge[cnt].p=v; edge[cnt].next=head[u]; head[u]=cnt++; } void dfs(int x, int fat) {id[x]=++mark;fa[x][0]=fat;for (int i=1; bin[i]<=dep[x]; ++i) fa[x][i]=fa[fa[x][i-1]][i-1];for (int i=head[x]; i; i=edge[i].next) {int v=edge[i].p;if (v==fat) continue;dep[v]=dep[x]+1;dfs(v,x);} } int dp_dfs(int x) {if (vis[x]) {for (int i=head[x]; i; i=edge[i].next) {int v=edge[i].p;if (dp_dfs(v)) ans++;}head[x]=vis[x]=0;return 1;}else {int tot=0;for (int i=head[x]; i; i=edge[i].next) {int v=edge[i].p;tot+=dp_dfs(v);}head[x]=vis[x]=0;if (tot>1) {ans++; return 0;}else return tot;} } int lca(int x, int y) {if (dep[x]<dep[y]) swap(x,y);int t=dep[x]-dep[y];for (int i=0; bin[i]<=t; ++i) if (bin[i]&t) x=fa[x][i];if (x==y) return x;for (int i=19; i>=0; --i) if (fa[x][i]!=fa[y][i]) x=fa[x][i], y=fa[y][i];return fa[x][0]; } void sol() {int m=Scan();cnt=1; top=0, ans=0;FOR(i,1,m) h[i]=Scan(), vis[h[i]]=1;sort(h+1,h+m+1,comp);FOR(i,2,m) if (vis[fa[h[i]][0]]) {puts("-1");FOR(i,1,m) vis[h[i]]=0;return ;}st[++top]=1;int P=h[1]==1?2:1;FOR(i,P,m) {int f=lca(h[i],st[top]);while (dep[f]<dep[st[top-1]]) add_edge(st[top-1],st[top]), top--;add_edge(f,st[top--]);if (f!=st[top]) st[++top]=f;st[++top]=h[i];}while (top>1) add_edge(st[top-1],st[top]), top--;dp_dfs(1);printf("%d\n",ans); } int main () {bin_init();int n, q, u, v;n=Scan();FO(i,1,n) u=Scan(), v=Scan(), add_edge(u,v), add_edge(v,u);dfs(1,0);q=Scan(); mem(head,0);while (q--) sol();return 0; }
View Code
E.Puzzle Lover(待填坑)
转载于:https://www.cnblogs.com/lishiyao/p/6255950.html
cf Round 613相关推荐
- Codeforces Round #613 (Div. 2)(B-D)
Codeforces Round #613 (Div. 2) B -抢时间&手感生疏->(第n + 1次)被long long卡掉- C 又一次败给了常识-EC的M题也是一个关于素数的暴 ...
- 【codeforces】【比赛题解】#915 Educational CF Round 36
虽然最近打了很多场CF,也涨了很多分,但是好久没写CF的题解了. 前几次刚刚紫名的CF,太伤感情了,一下子就掉下来了,不懂你们Div.1. 珂学的那场我只做了第一题--悲伤. 这次的Education ...
- 【codeforces】【比赛题解】#849 CF Round #431 (Div.2)
cf的比赛越来越有难度了--至少我做起来是这样. 先看看题目吧:点我. 这次比赛是北京时间21:35开始的,算是比较良心. [A]奇数与结束 "奇数从哪里开始,又在哪里结束?梦想从何处起航, ...
- 【codeforces】【比赛题解】#937 CF Round #467 (Div. 2)
没有参加,但是之后几天打了哦,第三场AK的CF比赛. CF大扫荡计划正在稳步进行. [A]Olympiad 题意: 给\(n\)个人颁奖,要满足: 至少有一个人拿奖. 如果得分为\(x\)的有奖,那么 ...
- 【codeforces】【比赛题解】#960 CF Round #474 (Div. 1 + Div. 2, combined)
终于打了一场CF,不知道为什么我会去打00:05的CF比赛-- 不管怎么样,这次打的很好!拿到了Div. 2选手中的第一名,成功上紫! 以后还要再接再厉! [A]Check the string 题意 ...
- cf Round#779 D 388535
前言: 这个方法挺慢的,不如其他大佬们的方法(但是我看不懂他们写的),所以自己来搞个.最坏的情况是n^2的复杂度,但是基本到不了最坏的情况.而且可以D1,D2两题通用! 核心思想: 假设 l^x=a1 ...
- 【codeforces】【比赛题解】#851 CF Round #432 (Div.2)
cf真的难-- 点我浏览丧题. [A]Arpa和她对墨西哥人浪的研究 Arpa正在对墨西哥人浪进行研究. 有n个人站成一排,从1到n编号,他们从时刻0开始墨西哥人浪. 在时刻1,第一个人站起来. 在时 ...
- CF Round#240题解
第一次参加CF的比赛,MSK19.30,四个小时的时差真心累,第一次CODE到这么夜-- 一开始做了A,C两题,后来做B题的时候我体力和精神集中度就很低了,导致一直WA在4-- 今天起床后再刷B,终于 ...
- CF Round #426 (Div. 2) The Useless Toy 思维 水题
题目链接: http://codeforces.com/contest/834/problem/A 题目描述: 输入起始状态和结束状态和数列长度, 判断旋转方向是顺时针逆时针还是不合理 解题思路: 长 ...
最新文章
- Android 删除无用的导包
- Jquery的Split二次分割
- HeartBeat 集群组件概述
- Cortex-M3-建立堆栈
- Angular元素属性绑定的一个例子
- 改进协议 BIP32-39-44概述
- java.util.Locale简介
- element 输入框点击事件_Element Input输入框的使用方法
- 部署KMS激活后用户端一些情况的确认
- 基础:用android开发的ASCII码转换器
- WinHttp编程步骤
- 用计算机运算符编写检索式,检索式
- 【NLP】中文分词方法:规则分词(正向最大匹配、逆向最大匹配、双向最大匹配)
- 【彩虹 钢琴伴奏】笔记
- 苹果cmsv10动漫二次元主题网站模板免费源码
- 李开复创业两年记:创新工场的孵化之困
- JavaScript 排序,不只是冒泡
- android tv 实现弹出通知
- 注册测绘师资格拟认定人员公示名单
- 用python画花球_只靠一把小小剪刀!她把这些花养成了花球!
热门文章
- 梯度下降法快速教程 | 第二章:冲量(momentum)的原理与Python实现
- 机器学习(十)Mean Shift 聚类算法
- 乘法更新规则对于并发的非负矩阵分解和最大间隔分类
- android开发板功能,Android中NFC模块PN532开发板应用/原理图/PCB等全部资料
- idea可以使用flash框架吗_可以使用 C# 的 Web 前端框架 Blazor
- 虚拟机的磁盘扩大超过2T,发现超过2T的这部分无分区
- python 大众点评模拟登陆_python项目实战:模拟登陆163邮箱,简单到爆
- java经典面试题目
- Mongodb最基础入门教程
- PyCharm Python迁移项目