[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 ...
随机推荐
- POJ 3279 Fliptile ( 开关问题)
题目链接 Description Farmer John knows that an intellectually satisfied cow is a happy cow who will give ...
- MSSQL 数据库性能优化
优化数据库的注意事项: 1.关键字段建立索引. 2.使用存储过程,它使SQL变得更加灵活和高效. 3.备份数据库和清除垃圾数据. 4.SQL语句语法的优化. 5.清理删除日志. SQL语句优化的基本原 ...
- javascript延迟对象
1.模拟任务队列: function taskQueue() { var taskList = []; var isRun = false; this.addTask = function (task ...
- javascript工厂模式、单例模式
//工厂模式 function createObject(name,age){ var obj = new Object(); obj.name = name; obj.age = age; obj. ...
- Python-字符串处理 str.format()
Python中内置的%操作符可用于格式化字符串操作,控制字符串的呈现格式.Python中还有其他的格式化字符串的方式,但%操作符的使用是最方便的. 另外python还有一个更强大的字符串处理函数 st ...
- twemproxy 简介、安装配置
twemproxy 简介.安装配置 http://www.xuchanggang.cn/archives/993.html
- nodejs 优雅的连接 mysql
1.mysql 及 promise-mysql nodejs 连接 mysql 有成熟的npm包 mysql ,如果需要promise,建议使用 promise-mysql: npm:https:// ...
- 在Github里集成Readthedocs服务
Readthedocs支持Markdown格式和sphinx格式的文档排版,是部署项目文档的绝佳平台.利用Github的托管服务,我们可以方便地将文档托管于Github,并利用Readthedocs查 ...
- Codeforces 707C Pythagorean Triples(构造三条边都为整数的直角三角形)
题目链接:http://codeforces.com/contest/707/problem/C 题目大意:给你一条边,问你能否构造一个包含这条边的直角三角形且该直角三角形三条边都为整数,能则输出另外 ...
- ZOJ-3319
Islands Time Limit: 1 Second Memory Limit: 32768 KB There are N islands and some directed paths ...