11月参加各种各样的比赛碰到的有趣的题目
目录
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;
}
}
}