HDXM,给点支持吧啊,练了一晚上的科三了,十点多才到家,每天还要早起准备各种东西,也是有点辛苦了。
问题 A: 能量消耗 cost
题目描述
Rainy7 的一生注定不平凡。
在一次睡梦中,她梦见自己来到了一个陌生的地方:四面是高大威严的石壁,脚下是一条径直通向前方的路。她抬头向前望去,在远处,隐隐约约地,有一把椅子,那是古时候国王做的椅子。椅子上坐着一位老者,白发银须,饱经风霜的脸上挤满了皱纹。他慈祥地注视着 Rainy7 ,面带微笑,右手拿着一根似乎有着无比强大的力量的法杖,顶部深蓝色的水晶在黑暗的环境下发着光,显得格外引人注目。等 Rainy7 走近之后,老者开口了:
” 孩子,我是魔法王国的国王。魔法王国是一个神奇,虚幻的王国,里面的每位居民都有强大的魔法。但是,有居民凭借着自己强大的魔法,到处作恶,屠杀其他居民,打破了王国的安宁,人们称他为恶人。我将此人封印在此地。为了保证他不再出去作乱,我日日夜夜地守在这里。现在,我年纪大了,恐怕没多少日子了,所以我打算找一个人来接替我,而这个人,就是你。孩子,我将要把我的魔法全部传授给你,你愿意成为我的继承人吗?"
Rainy7 犹豫了一会儿:强大的魔法?听起来很不错的样子,但我如果成为国王,能将魔法王国管理好吗?
但她还是没能抵住魔法的诱惑,最终说到:“我愿意。”
老者却说:" 我很高兴你将要成为我的继承人。不过在这之前,你需要先通过一个考核。
请听题:
你有许多种魔法,每一种魔法有一个对应的编号。
你每次施法消耗的能量为所施的魔法的编号的二进制表示法中 1 的个数。
对于每一个给定的魔法,你需要求出每次施法消耗的能量。"
输入
第一行一个整数T,表示老者一共询问T次。
接下来T行,每行一个整数N,表示每次询问的魔法的编号。
输出
输出共T行。
对于每一次询问,输出一行一个整数Ans,表示施法需要消耗的能量。
样例输入
1
7
样例输出
3
提示
样例解释:7的二进制表示法为 111 ,含3个 1,所以施法消耗的能量为3。
对于全部数据,1≤T≤1e5,0≤N≤1e18
思路:数据有点大,没法直接调用函数__builtin_popcountll(n) 。这是一个小模板,手写一个函数调用,大致2种写法。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll t,n;
int oneNumInBinary(ll n) { // 求十进制数的二进制中1的个数
ll cnt=0;
while(n) n=n&(n-1),cnt++;
// 或者 while(n) cnt+=n%2, n/=2; 容易理解一些
return cnt;
}
int main()
{
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
printf("%lld\n",oneNumInBinary(n));
}
return 0;
}
/*
数据不大时可以直接调用一个函数:__builtin_popcountll(n)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll t,n;
int main()
{
scanf("%lld",&t);
while(t--) {
ll n ;
scanf("%lld",&n);
cout << (__builtin_popcountll(n)) << endl ;
}
return 0;
}
*/
顺带提一下十进制转其他进制的通用模板:
问题 B: 能量树 tree
题目描述
5 月 2 日的模拟赛太良心了。
各位 dalao 们全都先把五校题 A 了。
“这题好水!”
“你说这出题人出这种水题给我们干嘛?”
“就是!这么水的动规当我们是小萌新吗?”
CaBeF_Yyx 听了十分伤心:为什么我老是被 D 呢?
Rainy7 成功回答出了老者的问题,成为了魔法王国的国王,统治者整个王国。
但是她管理得不太好。因为她经常施展某些奇怪的法力。
今天她又施法了,人们都忘了自己的的上司和下属是谁了。
魔法王国的大臣 chen03 通过研究发现,只要把每种情况都搜一遍。人们会在正确的情况下被体内微弱的法力唤醒,恢复记忆。
Rainy7 命令 CaBeF_Yyx 把所有情况算出来。
可是 CaBeF_Yyx 太蒻了,绞尽脑汁想了好多天都没有想出来,于是她只能把任务交给你。
所有情况:把王国里的人及职务看作一棵树,Rainy7 是根。求所有的树情况。
输入
一行,正整数Q ,表示询问次数。
接下来Q行,每行一个整数N ,表示这时王国里的人数(包括 Rainy7 ),你要完成事件的计算。(由于你没有膜法计算机,答案mod 1e9+9)
输出
Q 行,每行一个整数,表示该次询问的 所有情况。
样例输入
1
3
样例输出
3
提示
对于全部数据,1≤Q≤104,1≤N≤109
思路:
一开始以为这题是求卡特兰数,也就是常说的 “给出n个节点,求不同形态的二叉树的个数”。但是卡特兰数只能进行二叉树问题的求解,而题目没有限制树是二叉树。
这题其实是根据prufer序 ,求无根树的个数。n为1是,特判输出1;其他情况用快速幂算一下n^(n -2)输出。
介绍一下无根树:
有根树的话,就是在无根树的基础上,取任意一个结点为根,让结点之间形成父子关系。
可以根据下方链接对 “树” 进行更加深入、具体的了解。
树的基本概念、有根树和无根树的区别
解题的具体过程根据下方AC代码理解
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 1e9+9;
ll qpow(ll a,ll b) {
ll ans=1;
while(b) {
if(b&1) ans=(ans*a)%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
ll q,n,ans;
int main()
{
cin>>q;
for(int i=1;i<=q;i++)
{
scanf("%lld",&n);
if(n==1) cout<<1<<endl;
else {
ll ans=qpow(n,(n-2));
cout<<ans<<endl;
}
}
return 0;
}
顺便提一下无根树转有根树的c++模板:
#include <bits/stdc++.h>
using namespace std;
vector<int> v[100];
int p[100];
void dfs(int p1, int p2)
{
for(int i = 0; i < v[p1].size(); i++)
{
int h = v[p1][i];
if(h != p2)dfs(h, p[h] = p1);
}
}
int main()
{
int root, n;
cin >> root >> n;
for(int i = 1; i < n; i++)//n个定点有n-1条边
{
int a, b;
cin >> a >> b;
v[a].push_back(b);
v[b].push_back(a);
}
p[root] = -1;
dfs(root, -1);
}
问题 D: 台风
题目描述
您正在机房看小猪佩奇,忽然间您听说有台风要来,机房可能会停电。于是您急切地想知道台风将影响机房多久。
我们可以将台风抽象成圆心为O点,半径为r的圆,圆心O点即为台风的风眼。若以该平面建立平面直角坐标系,则台风圆心O的移动轨迹可表示为一条直线y=kx+b(假设其从极远的地方来)。机房的坐标为(m,n)。
现在台风以水平方向(沿x轴方向)每秒一个单位的速度靠近机房移动。您需要回答台风将影响机房多长时间(当机房落在台风的圆内或边界上时,就算做受到影响)。
输入
输入将严格遵循以下格式:r k b m n
输入一行五个实数 r,k,b,m,n(∣r,k,b,m,n∣≤1000,r≥0,保证都不超过 2 位小数)。
输出
输出仅一行一个实数,表示台风影响到机房的时间(单位:秒),四舍五入保留三位小数。
样例输入
5 -1 0 0 0
样例输出
7.071
思路:这好像是初中的经常遇到的数学题…要我们编程去实现。画图理解,运用三角函数去解即可。注意输出0.000的特判。(根据题意,斜率是一定存在的,无需考虑)
#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
int main()
{
double r,k,b,x,y,m,n;
cin>>r>>k>>b>>m>>n;
double juli=abs( (k*m-n+b)/(sqrt(k*k+1)) );
double jiaodu=atan(k);
double d=sqrt(r*r-juli*juli);
double ans=cos(jiaodu)*2*d;
ans=abs(ans);
if(juli>=r) printf("0.000\n");
else printf("%.3lf\n",ans);
return 0;
}