11月份刷题心得

11月参加各种各样的比赛碰到的有趣的题目   

目录

                        1. Cly的三角形

                        

                         2. 猫生律

                       

                         3.斐波那契 

1. Cly的三角形 

题目描述

Cly很喜欢三角形,有一天他遇到了一道和三角形有关的题,但是这道题他简单了,他懒得做,于是交给了你。
给定一个数组,每次询问一个子区间,如果能从这个子区间挑出三个数组成三角形输出clynb,否者输出clycdd。

输入

第一行给出数组大小n,查询次数q (1<=m,q<=1e5)
接下来一行输入n个数,表示a[i] (1<=a[i]<=1e9)
接下来q行,每行输入两个数l,r,代表一个子区间 (1<=l,r<=n)

输出

对于每个询问输出clynb或者clycdd

样例输入 Copy

5 3
2 1 4 3 5
1 2
1 3
3 5

样例输出 Copy

clycdd
clycdd
clynb

 总结:刚开始总是超时,在试图取子串再用排序加遍历找到一对可以组成三角形的组合

但是TLE说不你不行;

后来看完大佬的题解。。。。

原来是斐波那契数列;要组成三角形 那么两边之和至少大于第三边,而斐波那契数列刚好是前两项之和大于第三边,并且他的输入中没有超过int范围的 而斐波那契数列第45相开始int 就爆掉了;所以可以考虑当r-l+1的范围大于45的时候 又因为a[i]的范围在1e9之内,我们可以推出:从第45项开始知数列不满足a[i]=a[i-1]+a[i-2],此时必能形成三角形;(不满足:例如a[47]已经超出范围所以a[45]和a[46]因为要满足a[i]<1e9,所以a[45]+a[46]不可能超过a[47])

所以只要先判断范围是不是超过45,如果不超过也最多只要遍历排序后的(45-2)项就可以了,不会超时;

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+10;
long long num[N];
long long temp[N];
int main()
{
	int n;
	cin>>n;
	int q;
	cin>>q;

	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&num[i]);
	}

	while(q--)
{
	int l,r;
	scanf("%d %d",&l,&r);
	int len =r-l+1;
	if(len >= 45){//超过45项直接判断可以组成
		cout<<"clynb"<<endl;
	}
	else if(len<=2)
	{//小于三项直接判断不能组成
		cout<<"clycdd"<<endl;
	}
	else{//遍历l到r范围内的每三项就可以
	for (int i = 0; i < len; i++) {
				temp[i] = num[i + l];//用temp存储l-r范围内的num;便于排序;
			}
			sort(temp, temp + len);//升序排序;
		for(int i=0;i<len-2;i++)
		{
			//cout<<b[i]<<" "<<b[i+1]<<" "<<b[i+2]<<endl;<--本句测试用可删除
			if(temp[i]+temp[i+1]>temp[i+2]){				
				cout<<"clynb"<<endl;
                goto out;//找到可以就出去
			}
		}

		cout<<"clycdd"<<endl;
            out:;//出口
		
	}
}

}

2. 猫生律

题目描述

五度相生律是一种按照自然泛音的纯五度关系依次产生音序( 5 声, 7 声,12 音)的生律方式。

1. 取一基准音,在此以 C 为例,将其频率 f 乘上 3/2 ,即升高完全五度得下一音 G。

2. 再将 G 升高完全五度得下一音 D ,此时 D 之频为 (3f/2)*(3/2)=9f/4 ,高于原基准音之倍频 2f ,故将其除二,即降八度得   9f/8。

3. 再将 D 升高完全五度得下一音 A ,此时 A 之频为 (9f/8)*(3/2)=27f/16。

4. 再将A升高完全五度得下一音 E,此时 E 之频为 (27f/16)*(3/2)=81f/32,高于原基准音之倍频 2f ,故将其降八度得81f/64


5. 再将 E 升高完全五度得下一音 B ,此时 B 之频为  (81f/64)*(3/2)=243f/128。

一般来说,七声音阶中的六声都能运用此规律求出。但猫猫不满足于此,他希望依照一样的规律推算出 C 任意下个音频率与 C 频率 f 的比值,请输出它。

输入

第一行包含一个正整数 T ,代表测试组数。 (1<=T<=10)

随后 T 行,每行包含一个正整数 n ,代表与 C 比较频率的是 C 以下的第 n 个音频。 (1<=n<=109)

输出

输出 T 行,代表答案,如果输出与正确结果的误差小于 10-5 ,你的答案将被认为是正确的。

样例输入 Copy

3
1
2
3

样例输出 Copy

1.50000
1.12500
1.68750

 思路:快速幂并且判断是否大于2;

#include<iostream>
using namespace std;
typedef long long ll;
double quickpow(double a,long long b){
	if(a==0) return 0;
	if(b==0) return 1;
	if(b==1) return a;
	double temp =quickpow(a,b / 2);
	double res =temp*temp;
	while(res >=100000)
	{
		res*=0.5;
	}
	return b%2==0? res:res*a;
}
int main(){
	double C=1.5;
	int T;
	cin>>T;
	for(int i=0;i<T;i++){
		double ans=1;
		int n;
		cin>>n;
		for(ll j=1;j<=n/100000;j++)
		{
			ans=ans*quickpow(C,100000);
			while(ans >=2 ){
				ans*=0.5;
			}
		}
		for(ll j=1;j<=n%100000;j++){
			ans=ans*1.5;
			if(ans>=2){
				ans=ans*0.5;
			}
		}
		while(ans>=2){
			ans*=0.5;
		}
		printf("%.5lf\n",ans);
	}
}

3.斐波那契 

题目描述

Fibonacci numbers are well-known as follow:

f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2);

Now given an integer N, please find out whether N can be represented as the sum of several Fibonacci numbers in such a way that the sum does not include any two consecutive Fibonacci numbers.

输入

Multiple test cases, the first line is an integer T (T <= 10000), indicating the number of test cases.
Each test case is a line with an integer N (1 <= N <= 1000000000).

输出

One line per case. If the answer don’t exist, output "-1" (without quotes). Otherwise, your answer should be formatted as "N=f_1+f_2+……+f_n". N indicates the given number and f_1, f_2,…… , f_n indicating the Fibonacci numbers in ascending order. If there are multiple ways, you can output any of them.

样例输入

4 5 6 7 100

样例输出

5=5 6=1+5 7=2+5 100=3+8+89

 思路:dfs暴力搜索解即可;记得倒着搜索不然容易超时;记得升序输出

#include<bits/stdc++.h>
using namespace std;
int num[1001];
int b[1001]{0};
int a[1001];
int flag=0;
int len=0;

void dfs(int sum,int l,int i,int flag1)
{
	if(sum==0){
		flag=1;
		len=l-1;
		return ;
	}
	for(int j=i;j>=1;j--){
		if(flag) return;
		if( sum>=num[j]  ){
			if(  b[j]!=1 && (l==1 || abs(flag1-j)!=1 ))
			{
				a[l]=num[j];
				 b[j]=1;
				dfs(sum-num[j],l+1,j-1,j);
				 b[j]=0;
			}
		}
	}
	
}

void reset(){
	flag=len=0;
	memset(b,0,sizeof(b));
} 
int main(){
	num[1]=1;
	num[2]=1;
	for(int i=3;i<=1000;i++){
		num[i]=num[i-1]+num[i-2];
	}

	int T;
	cin>>T;
	while(T--)
	{ 	
		reset();
		int sum;
		cin>>sum;
		dfs(sum,1,45,1);
		if(flag==0){
			cout<<"-1"<<endl;
		}
		else
		{

			printf("%d=",sum);
			for(int i=len;i>=1;i--){
				printf("%s%d",i==len?"":"+",a[i]);
			}
			cout<<endl;
		}
	
	}

}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值