UPC 2020年夏混合个人训练第八十一场

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;
}

猜你喜欢

转载自blog.csdn.net/Luoxiaobaia/article/details/108066047
UPC