UOJ283 直径拆除鸡

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000 
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

题目链接:http://uoj.ac/problem/283

正解:枚举+数学

解题报告:

  这道题很神啊,我在考场上想了一下,觉得菊花树很正确,但是想想就会发现菊花树的答案稳定在2*n-1上,并不优秀。

  题解说的很明白了,我们先枚举链的条数,计算出最优值,只需在算出的最优链数上连边即可。

  有一些小trick,需要注意。

  题解:http://vfleaking.blog.uoj.ac/blog/2292

  

//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <complex>
using namespace std;
typedef long long LL;
int n,m,now,tot;
int ans,chain,last;
inline int getint(){
    int w=0,q=0; char c=getchar(); while((c<‘0‘||c>‘9‘) && c!=‘-‘) c=getchar();
    if(c==‘-‘) q=1,c=getchar(); while (c>=‘0‘&&c<=‘9‘) w=w*10+c-‘0‘,c=getchar(); return q?-w:w;
}

inline void work(){
	n=getint(); m=getint();
	for(int i=1;(i+1)*(i+1)<=n;i++) {//枚举链的条数
		now=0; tot=n;
		for(int j=i;j>=1;j--)
			now+=tot,tot-=2*j+1;
		now+=tot;
		if(now>ans) ans=now,chain=i;
	}
	tot=0; last=0;
	for(int i=chain;i>=1;i--) {//连边
		for(int j=1;j<=2*i;j++)
			printf("%d %d\n",tot+j,tot+j+1);
		if(tot>0) printf("%d %d\n",last,tot+i+1);
		last=tot+i+1; tot+=i*2+1;
	}
	if(chain==0) last=1,tot=1;
	while(tot<n) { tot++; printf("%d %d\n",last,tot); }
}

int main()
{
    work();
    return 0;
}

  

时间: 2024-09-30 16:35:49

UOJ283 直径拆除鸡的相关文章

UOJ#283. 直径拆除鸡

UOJ#283. 直径拆除鸡 题意: 题目传送门 题解: 只能说是好妙的一个构造啊--(开花金字塔这名字真形象--) 考虑删除掉一条长度为\(d\)的直径之后,最长的直径是\((\lfloor \frac{d}{2} \rfloor - 1) * 2\).这个还是比较容易证明的,发现由于这个式子中有一个下取整的部分,所以当直径为偶数的时候,利用率是最高的.这是其中的一个结论. 然后另一个容易得出的结论就是,当一个联通块删除直径之后被分成两个联通块时,每个点产生的贡献相比于一个联通块的时候会减小,

UOJ Goodbye Bingshen

在叶子童鞋的推荐下打了这场比赛... 感觉被虐爆了... 怎么这么多构造题... 我还没写过呢... 交互题是毛线...看了好久没看懂...就放弃了...(我语文好差QAQ...) 最后只会T1...T2没时间了,就随便水了一发...居然拿了30分(rp--)... 下面有一些是自己/小伙伴YY的想法...有一些是题解...先放官方题解... 就不放题面了...复制过来效果很神奇... A. 长度测量鸡 分析: 这个你脑补一下,划分成的长度一定是1~n的某个全排列,然后算一算,发现能够组合出来的

《鸡啄米C++编程入门系列》系列技术文章整理收藏

<鸡啄米C++编程入门系列>系列技术文章整理收藏 收藏整理鸡啄米C++编程入门系列文章,供个人和网友学习C++时参考 1鸡啄米:C++编程入门系列之前言 2鸡啄米:C++编程入门系列之一(进制数) 3鸡啄米:C++编程入门系列之二(原码.反码与补码) 4鸡啄米:C++编程入门系列之三(VS2010的使用介绍) 5鸡啄米:C++编程入门系列之四(数据类型) 6鸡啄米:C++编程入门系列之五(运算符和表达式) 7鸡啄米:C++编程入门系列之六(算法的基本控制结构之选择结构) 8鸡啄米:C++编程入

poj 1985 Cow Marathon 【树的直径】

题目:poj 1985 Cow Marathon 题意:给出一个树,让你求树的直径. 分析: 树的直径:树上两点之间的最大距离. 我们从任意一点出发,BFS一个最远距离,然后从这个点出发,在BFS一个最远距离,就是树的直径. AC代码: /* POJ:1985 Cow Marathon 2014/10/12/21:18 Yougth*/ #include <cstdio> #include <iostream> #include <algorithm> #include

APIO2010巡逻(树上带权直径)

题目链接:https://www.luogu.org/problem/show?pid=3629 题解: 看到这题题解一片空白,身为蒟蒻的我也想为社会做点贡献-- 首先要知道: 1.假如不加边,每条边都要走两次. 2.假如加了一条边,那么会形成一个环,而且环上的边只需要走一次,其余的边要走两次. (自己yy以下就可以知道了) 对于k=1的话,我们就要使环上的边尽量多,也就是说我们要找树的直径,使得树的直径在环内. 而对于k=2的话,再加一条边的时候,会再多一个环. 这时我们要知道: 1.如果一条

C/C++算法竞赛入门经典Page9 例题1-4 鸡兔同笼

题目:鸡和兔总数:n,总腿数:m.输入n,m,输出鸡和兔分别的数量;无解则输出"No answer" 样例输出1: 14 32 样例输出1: 12 2 样例输入2: 10 16 样例输出2: No answer 首先,声明两个变量n,m对应总数和总腿数;再声明两个变量为鸡和兔各自的数量a,b 1 int n,m,a,b; 输入n,m: scanf("%d%d",&n,&m); 通过联立方程组: a+b=n 2a+4b=m 得: a=(4n-m)/2;

鸡国福利

鸡国福利 时间限制: 1 Sec  内存限制: 128 MB 题目描述 鸡国为了表彰鸡国每一只鸡在过去一年的优秀表现,打算在接下来的 n 天中每天给鸡国的一只鸡发 1 袋或者 2 袋“鸡币”(鸡国的通用货币)作为福利.国王要求每天来领钱鸡互不相同,即来领过钱的鸡不能再来,否则将受到严厉的处罚. 但聪明的鸡国老百姓侦察后发现国王每天发的钱袋子里面装的钱数量是不一样的(同一天的相同),第 i 天发的每一袋钱为 a i 元.如果第 i 天来领钱的鸡领 1 袋钱,它可以获得ai 元的“鸡币”,如果它领

3. 百钱买白鸡问题

这是一个古老而非常经典的问题,最早源自中国古代的算经,中国古代数学家张丘建在他的算经中提出了著名的百钱买白鸡的问题: 鸡翁1, 值钱5,鸡母1,值钱3,鸡雏3值钱1,百钱买白鸡,问翁,母,雏各几何? 100文钱买100只鸡,公鸡5文钱一只,母鸡3文一只,小鸡3只1文钱:100文钱买了100只鸡,请问公鸡,母鸡,小鸡各有多少? #include <stdio.h> #include <stdlib.h> int main() {     int i,j,k;     for(i=0;

树讲解(2)——树的输入,重心,直径

one.树的输入 1.输入每个节点父亲节点的编号 #include<vector> #include<stdio.h> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 100000 #define maxn 123456 using namespace std; int n,x,fa[N]; bool vis[N]