列表

详情


NC200311. H-绵羊的银币

描述

我断然没想到面前这景象,被黑雾所包围的众兽,以及那辆由金角鹿所驱动的战车。
「显然你已经知道我是谁了吧」那个女人抚摸着金角鹿身上的皮毛
「阿尔忒弥斯,司掌狩猎和野兽的狩猎女神」我有点头疼,居然连这种神祇都能召唤而来,那个圣杯的确是个不得了的问题
「不错,我即是七骑之中的弓之骑士(archer)」她似乎很乐于享受这场闹剧「你只需要回答我的一个问题就可以继续前行了,若不能的话,最好你有百般武艺」
「洗耳恭听」我掏出一根雪茄点燃,想缓解一下自己
「曾有一个牧羊人和一个商人进行交易,但他们对交易的价格争执不下,最终他们来寻求我的智慧。但是我并不想他们过于轻易的得到神的帮助,于是我便提出一个规则。如果当前商人要向牧羊人购买一定数量的羊,那么价格应当等于购买这个数量的四分之一的羊的价格加上购买这个数量的一半的羊的价格。显然,羊只能一整只的卖出,而不能半只卖出,所以当这个数量不能被分成四份或两份,就应该下取整,这是对商人的优惠」
「这个问题最终会回到购买数量很小的情况」
「不错,商人不买羊,就不需要支付银币,而如果他购买一只羊,那么他需要支付一枚银币」她没有停下手上的动作「无论最始的数量多大,都会回归到一和零上面。想必你已经有了快捷计算出需要支付的金额的办法了吧,即使没有我也要开始提问了,若是无法回答,愿君安息」
我的脑中浮现了这三个公式
f[0] = 0 f[1] = 1 f[n] = f[n/2] + f[n/4]  (n>=2)

输入描述

第一行一个整数T ( 1 <= T <= 250000 ) ,表示T次询问。
下面T行,每行一个整数n ( 0 <= n <= 1018 ) ,表示当前需要购买多少只绵羊
由于输入输出过多,请使用scanf和printf,否则容易超时
n极大,log2(n)精度不够,请不要使用<math.h>的任何log函数,否则容易Wrong Answer

输出描述

对于每个询问,输出需要支付的银币数量

示例1

输入:

4
1
2
3
4

输出:

1
1
1
2

原站题解

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

C(clang11) 解法, 执行用时: 102ms, 内存消耗: 3540K, 提交时间: 2020-12-05 18:08:12

#include<stdio.h>

int main()
{
	long long i,j=0,k=0,t,n,l,a[10000];
	a[0]=1,a[1]=2;
	scanf("%lld",&t);
	
	for(l=0;l<t;l++,k=0){
		scanf("%lld",&n);
		if(n==0){
		printf("0\n");
		continue;}
		for(i=4;i-1<n;i=i*2)
		k++;
	for(i=2;i<=k;i++)
	{
		a[i]=a[i-1]+a[i-2];
		
	}
	printf("%lld\n",a[k]);
}}

C++11(clang++ 3.9) 解法, 执行用时: 565ms, 内存消耗: 3688K, 提交时间: 2019-12-07 21:15:32

#include<iostream>
#include<cstring>
using namespace std;
long long t,n,i,f[200];
int main()
{
	f[1]=f[2]=1;
	for(int i=3;i<=100;i++)f[i]=f[i-1]+f[i-2]; 
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(i=0;(1ll<<i)-1<n;i++);
		cout<<f[i]<<endl;
	}
}

C++14(g++5.4) 解法, 执行用时: 604ms, 内存消耗: 3576K, 提交时间: 2019-12-07 21:36:58

#include<bits/stdc++.h>
using namespace std;
long long t,n,i,f[200],sum=1;
int main()
{
	f[1]=f[2]=1;
	for(int i=3;i<=100;i++)f[i]=f[i-1]+f[i-2]; 
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(i=0;(sum<<i)-1<n;i++);
		cout<<f[i]<<endl;
	}
}

Python3(3.5.2) 解法, 执行用时: 3661ms, 内存消耗: 6604K, 提交时间: 2019-12-15 16:47:54

d=[0,1,1]
for i in range(3,61):
	d.append(d[i-2]+d[i-1])
for i in range(int(input())):
	n = int(input())
	j=0
	while((1<<j)-1<n):j+=1
	print(d[j])

pypy3 解法, 执行用时: 1131ms, 内存消耗: 34416K, 提交时间: 2021-09-14 22:06:01

d=[0,1]
for i in range(2,61):d.append(d[i-2]+d[i-1])
for i in range(int(input())):
    n=int(input())
    print(d[len(bin(n))-2]if n else 0)

上一题