列表

详情


NC20650. 可爱の星空

描述

当你看向她时,有细碎星辰落入你的眼睛,真好。”——小可爱
在一个繁星闪烁的夜晚,卿念和清宇一起躺在郊外的草地上,仰望星空。
星语心愿,他们,想把这片星空的星星,连成一棵漂亮的树,将这美好的景色记录下来。
现在,天上共有n颗星星,编号分别为1,2.....n,一开始任何两个点之间都没有边连接。
之后,他们两个想在在(u,v)之间连无向边,需要付出|u联通块大小-v联通块大小|的代价。
他们两个想用最少的代价来使这n个点联通,所以他们想知道最小代价是多少。
(多组数据

输入描述

第一行一个正整数,表示数据组数T

接下来T行每行一个正整数,表示询问的n

输出描述

T行,每行一个数表示答案

示例1

输入:

1
5

输出:

2

说明:

1,2....5五个点,连边顺序为(1,2),(3,4),(1,5),(5,3),代价为0,0,1,1,总代价为2,是n=5的时候最优答案。

虽然(1,2),(2,3),(3,4),(4,5)也可以,但是代价为0,1,2,3,总代价为6,比2大。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 111ms, 内存消耗: 436K, 提交时间: 2023-01-11 13:29:19

#include<iostream>
#define ll long long int
ll dp(ll n){
	if(n==2||n==1)return 0;
	else if(n&1) return dp(n/2)+dp(n/2+1)+1;
	else return dp(n/2)*2;
}
using namespace std;
int main(){
	ll t,n;
	cin>>t;
	while(t--){
		cin>>n;
		cout<<dp(n)<<endl;
	}
}

JavaScript V8 解法, 执行用时: 237ms, 内存消耗: 7252K, 提交时间: 2023-07-19 15:57:33

let dfs = (n) => {
    if(n == 1 || n == 2) return 0;
    if(n & 1) return dfs(Math.floor(n/2)) + dfs(Math.floor(n / 2) + 1) + 1;
    else return dfs(n / 2) * 2
}

let t =readline()
while(t --) {
    let n = parseInt(readline())
    print(dfs(n))
}

C++(clang++ 11.0.1) 解法, 执行用时: 122ms, 内存消耗: 556K, 提交时间: 2023-07-30 09:52:05

#include<iostream>
using namespace std;
long long t,n;
long long f(long long n)
{
	if(n<=2)return 0;
	if(n&1)return f(n/2)+f(n/2+1)+1;
	return f(n/2)*2;
}
int main()
{
	cin>>t;
	while(t--){
		cin>>n;
		cout<<f(n)<<endl;
	}
    return 0;
}

Python3 解法, 执行用时: 224ms, 内存消耗: 9668K, 提交时间: 2021-11-28 15:59:11

d={1:0,2:0,3:1}
def f(n):
    if n in d:
        return d[n]
    if n%2==0:
        d[n]= f(n//2)*2
    else:
        d[n] = f(n//2)+f(n//2+1)+1
    return d[n]

T=int(input())
for i in range(T):
    n=int(input())
    print(f(n))

pypy3 解法, 执行用时: 753ms, 内存消耗: 27820K, 提交时间: 2022-12-23 17:21:43

def solve(n):
    if n==1 or n==2:return 0
    if n%2==0:return (solve(n>>1))<<1
    else:return solve(n>>1)+solve((n>>1)+1)+1
t=int(input())
while t>0:
    t-=1
    n=int(input())
    print(solve(n))

上一题