这场CF水题都非常的水,D题如果对树、DFS相关比较熟练的话也不难。比赛时前三题很快就过了,可是因为毕竟经验还是太少,D题就卡住了。比赛之后A题还因为没理解对题意fst了……(为什么这次就没人来hack我orz)。唉,本来发挥好一些这次上蓝名是很有可能的,只能等待下一次了。Z神这次顺利AK,差距还是太大,虽然有初学为理由,但这个烤漆之后就会到来的假期还是要好好加油了,要学要练的东西实在是太多了。
A题:
如果起点和终点是一家航空公司,那么显然0元就可到达。如果不是,0和1一定有一个分界处,先做起点的航空公司到分界处,再转1次不同航空公司的飞机,花去1元,之后再免费到终点即可。(理解错题意真是致命啊,以后再也不那么着急了……)
参考代码:
#include<stdio.h>
#include<bits/stdc++.h>
#include <iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n,st,en;
char a[];
int main()
{
scanf("%d%d%d",&n,&st,&en);
scanf("%s",a+);
if(a[st]==a[en])
printf("0\n");
else
{
printf("1\n");
}
return ;
}
B题
第i个数是多少,就是i的质因数分解中2的幂次是多少。当然也可以递归做。(CF当天晚上C++上机考的就是位运算orz)
#include<stdio.h>
#include<bits/stdc++.h>
#include <iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int main()
{
ll n,x;
scanf("%I64d %I64d",&n,&x);
ll an=;
while(!(x&))
{
x>>=;
an++;
}
printf("%I64d\n",an);
return ;
}
C题
这熟悉的数竞感觉……一看就知道一定是一个构造。2/n=1/n+1/(n+1)+1/n*(n+1)即可,(赛后看同学的代码,发现还真有暴力过的,给跪)。需要注意的是n=1时没有符合题意的解。
#include<stdio.h>
#include<bits/stdc++.h>
#include <iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int main()
{
ll n;
scanf("%I64d",&n);
if(n==)
{
printf("-1\n");
return ;
}
printf("%I64d %I64d %I64d\n",n,n+,n*(n+));
return ;
}
D题(重要!需要回顾)
因为从来没做过类似的树的问题,看到这道题时又有一种两个月前刚参加CF比赛时没见过pair的绝望。知道大概要怎样,可是因为对相关套路的不熟悉连给出的每一组树的节点怎样区分父节点和子节点都不知道……
建立vector后缀数组存储每个可能的父子结点关系。dfs遍历,确定整个树的父子关系,并且后序遍历,每次子树返回的时候就更新当前节点最大值,要输出的答案也在每个过程中进行更新。
#include<stdio.h>
#include<bits/stdc++.h>
#include <iostream>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int shu=2e5+;
const ll chu=2e9+;
int n,st[shu];
ll an=chu;
ll da[shu];
vector <int> re[shu];
ll dfs(int i,int fa)
{
priority_queue<ll> que;
int j;
ll hui=;
for(j=;j<re[i].size();j++)
{
int temp=re[i][j];
if(temp==fa)
continue;
ll a=dfs(temp,i);
da[i]=max(da[temp],da[i]);
que.push(da[temp]);
hui+=a;
}
hui+=st[i];
da[i]=max(da[i],hui);
if(que.size()>=)
{
ll oh=;
oh+=que.top();
que.pop();
oh+=que.top();
que.pop();
an=max(oh,an);
}
return hui;
}
int main()
{
scanf("%d",&n);
int i,tem,tarr;
for(i=;i<=n;i++)
{
scanf("%d",&st[i]);
da[i]=-chu;
}
for(i=;i<n-;i++)
{
scanf("%d %d",&tem,&tarr);
re[tem].push_back(tarr);
re[tarr].push_back(tem);
}
an=-chu;
dfs(,);
if(an==-chu)
printf("Impossible\n");
else
printf("%I64d\n",an);
return ;
}
最近校赛还是烤漆,E题就先不补了。