[Codeforces #196] Tutorial
Link:
A:
枚举
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+;
int n,m,dat[MAXN],res=<<; int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++) scanf("%d",&dat[i]);
sort(dat+,dat+m+);
for(int i=;i<=m-n+;i++)
res=min(res,dat[i+n-]-dat[i]);
printf("%d",res);
return ;
}
Problem A
B:
可以发现分母为$max(a*d,b*c)$,分子为$|a*d-b*c|$
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
int a,b,c,d,ta,tb,tc,td,resx,resy;
int GCD(int x,int y){return x%y==?y:GCD(y,x%y);} int main()
{
scanf("%d%d%d%d",&a,&b,&c,&d);
resx=abs(a*d-c*b),resy=max(a*d,c*b);
int gcd=GCD(resx,resy);
printf("%d/%d",resx/gcd,resy/gcd);
return ;
}
Problem B
C:
直接贪心,考虑将空格插入连续的序列中
如果可以不翻倍自然答案就是$m$,否则应当尽可能在前面翻倍来减少增加的分数
能推出翻倍$q$次后的分数为$(2^q-1)*2*k$,这样再加上剩余不翻倍的分数即可
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
const ll MOD=1e9+;
ll n,m,k,res;
ll quick_pow(ll a,ll b)
{
ll ret=;
for(;b;b>>=,a=a*a%MOD)
if(b&) ret=ret*a%MOD;
return ret;
} int main()
{
scanf("%I64d%I64d%I64d",&n,&m,&k);
if(!m||!n) return puts(""),;
ll rst=n-m,num=n/k;
if(rst>=num) res=m;
else res=(quick_pow(,num-rst)-)**k%MOD+(m-(num-rst)*k%MOD);
printf("%I64d",(res+MOD)%MOD);
return ;
}
Problem C
D:
官方题解:
将原树转化成有根树,对于一个点的最远关键点分成两类:
1、在该点的子树中,记最远距离为$MaxDown$
2、在树上的其它部分,记最远距离为$MaxUp$
对于1,明显可以$dfs$通过孩子节点来更新
对于2,又要分为两类来更新:
1、在其兄弟节点的子树中,即$MaxDown_{sibling}+2$
2、不在父亲节点的子树中,即$MaxUp_{father}+1$
其中注意用兄弟节点更新时要先记录最大/次大值来保证$O(1)$更新
不过感觉我的方法更简单啊……
先想想如何求一个点到树上任意点的最远距离
明显是用数的直径来解决的经典问题,可用反证法证明最远点一定是直径的两端
发现将任意点改为特定的关键点后该结论依然成立!
因此只要找到关键点中最远的点对$(a,b)$,对于每个点$v$判断$dist(a,v),dist(b,v)\le d$
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+;
int head[MAXN],tot;
struct edge{int nxt,to;}e[MAXN<<];
int n,m,d,x,y,p[MAXN],rt1,rt2,d1[MAXN],d2[MAXN],res; void add(int from,int to)
{e[++tot].nxt=head[from];e[tot].to=to;head[from]=tot;}
void dfs(int x,int anc,int *d)
{
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=anc)
d[e[i].to]=d[x]+,dfs(e[i].to,x,d);
} int main()
{
scanf("%d%d%d",&n,&m,&d);
for(int i=;i<=m;i++) scanf("%d",&p[i]);
for(int i=;i<n;i++)
scanf("%d%d",&x,&y),add(x,y),add(y,x); d1[]=;dfs(,,d1);
for(int i=;i<=m;i++) if(d1[p[i]]>d1[rt1]) rt1=p[i];
d1[rt1]=;dfs(rt1,,d1);
for(int i=;i<=m;i++) if(d1[p[i]]>d1[rt2]) rt2=p[i];
d2[rt2]=;dfs(rt2,,d2); for(int i=;i<=n;i++)
if(d1[i]<=d&&d2[i]<=d) res++;
printf("%d",res);
return ;
}
Problem D
虽说第一种解法可能代码量稍大,但分类方法还是很实用的:
将无根树转化成有根树后按照是否在该点的子树中分类
其中兄弟节点对该点的贡献不要忘记统计!我一开始就漏掉了……
E:
发现最优解除了叶子节点和根外,其它节点必然都属于$a$
考虑一个点向当前树插入,其要么接在某个节点后,要么重开一棵树
由于$n$只有8,明显排序预处理后枚举各种组合就好了
其中有一些技巧需要注意:
1、采取从根到叶子的构造更加方便
由于树根确定其叶子节点就已经确定,后面接点时就不用再考虑叶子节点的贡献了
2、不要漏考虑最大点本身就是根的情况,这样答案会减少1
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
ll n,dat[],dvs[],res=1ll<<; void dfs(int k,int sum,int rt)
{
if(k==n+)
{res=min(res,sum+ll(rt>));return;}
if(dvs[k]>) sum++; dfs(k+,sum+dvs[k],rt+);//单独成树
for(int i=;i<k;i++)//连在之前的节点后
if(dat[i]%dat[k]==)
dat[i]/=dat[k],dfs(k+,sum,rt),dat[i]*=dat[k];
} int main()
{
scanf("%I64d",&n);
for(int i=;i<=n;i++) scanf("%I64d",&dat[i]);
sort(dat+,dat+n+,greater<ll>());
for(int i=;i<=n;i++)
{
ll t=dat[i];
for(int j=;1ll*j*j<=dat[i];j++)
while(t%j==) t/=j,dvs[i]++;
if(t>) dvs[i]++;
} dfs(,,);
printf("%I64d",res);
return ;
}
Problem E
[Codeforces #196] Tutorial的更多相关文章
- Codeforces 196 E. Tricky and Cleve Password
\(>Codeforces \space 196\ E. Tricky\ and\ Cleve\ Password<\) 题目大意 : 给出一个有 \(n\) 个结点,\(m\) 条边的连 ...
- [Codeforces #172] Tutorial
Link: Codeforces #172 传送门 A: 一眼看上去分两类就可以了 1.每个矩形只有两条边相交,重合的形状为菱形 2.每个矩形四条边都有相交 对于情况1答案为$h*h/sin(a)$ ...
- [Codeforces #514] Tutorial
Link: Codeforces #514 传送门 很简单的一场比赛打崩了也是菜得令人无话可说…… D: 一眼二分,发现对于固定的半径和点,能包含该点的圆的圆心一定在一个区间内,求出区间判断即可 此题 ...
- [Codeforces #210] Tutorial
Link: Codeforces #210 传送门 A: 贪心,对每个值都取最大值,不会有其他解使答案变优 #include <bits/stdc++.h> using namespace ...
- [Codeforces #174] Tutorial
Link: Codeforces #174 传送门 A: 求原根的个数,有一条性质是原根个数为$\phi(\phi(n))$,多了一个不会证的性质 如果要确定哪些是原根的话还是要枚举,不过对于每个数不 ...
- [Codeforces #190] Tutorial
Link: Codeforces #190 传送门 A: 明显答案为$n+m-1$且能构造出来 #include <bits/stdc++.h> using namespace std; ...
- [Codeforces #211] Tutorial
Link: Codeforces #211 传送门 一套非常简单的题目,但很多细节都是错了一次才能发现啊…… 还是不能养成OJ依赖症,交之前先多想想corner case!!! A: 模拟,要特判0啊 ...
- [Codeforces #192] Tutorial
Link: Codeforces #192 传送门 前两天由于食物中毒现在还要每天挂一天的水 只好晚上回来随便找套题做做找找感觉了o(╯□╰)o A: 看到直接大力模拟了 但有一个更简便的方法,复杂度 ...
- Codeforces 196 C. Paint Tree
分治.选最左上的点分给根.剩下的极角排序后递归 C. Paint Tree time limit per test 2 seconds memory limit per test 256 megaby ...
随机推荐
- 【BZOJ】1984 月下“毛景树”
[算法]树链剖分+线段树 [题解]线段树的区间加值和区间覆盖操作不能同时存在,只能存在一个. 修改:从根节点跑到目标区域路上的标记全部下传,打完标记再上传回根节点(有变动才需要上传). 询问:访问到目 ...
- centos6.5下安装svn并且实现多项目管理配置方案
#安装SVN服务器 yum install subversion #在home下创建svn根目录 mkdir /home/svn #在 /home/svn下创建pro1 , pro2, pro3 三个 ...
- vue实现微信对话
因为项目中需要实现仿微信对话功能,于是抽空实现了下,主要是h5的canvas的把图片和文字绘制到画布上 原文来自我的个人博客:http://lvhww.com/index.php/archives/6 ...
- 【C语言】Coursera课程《计算机程式设计》台湾大学刘邦锋——Week6 String课堂笔记
Coursera课程 <计算机程式设计>台湾大学 刘邦锋 Week6 String 6-1 Character and ASCII 字符变量的声明 char c; C语言使用一个位元组来储 ...
- Vuex 基本概念
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 每一个 Vuex 应用的核心就是 stor ...
- linux编程之文件操作
在linux下用文件描述符来表示设备文件盒普通文件,文件描述符是一个整型的数据,所有对文件的操作都是通过文件描述符来实现的. 文件描述符是文件系统中连接用户空间和内核空间的枢纽,当我们打开一个或者创建 ...
- Linux汇编教程03:大小比较操作
我们在上一讲中,简单了解了汇编程序大概的样子.接下来我们来了解一下,汇编程序的大小比较操作.所以我们以编写寻找一堆数中的最大值作为学习的载体. 在编写程序之前,先要分析我们的目的,在得出解决方案. 目 ...
- lsb_release查看当前系统的发行版信息
Linux除了用uname -r查看系统版本信息外,还可以用lsb_release. 安装: yum install -y redhat-lsb-core 使用: lsb_release -a
- Python爬虫之百度API调用
调用百度API获取经纬度信息. import requests import json address = input('请输入地点:') par = {'address': address, 'ke ...
- mybatis 联结查询
一.查询 员工(tbl_employee)时,关联 查询出 员工对于的部门信息 (tab1_dept),一对一查询,或者多对一查询 适用 emp bean里面 包含 部门bean dept属性对象 1 ...