2041 超级楼梯
技巧:登上第10级台阶的走法=登上第9级台阶的走法+登上第8级台阶的走法。
是斐波那契数列。
递归方法:
#include<bits/stdc++.h>
int time(int n){
if(n==2 || n==1) return 1;
return time(n-1)+time(n-2);
}
int main(){
int n;
scanf("%d",&n);
while(n--){
int m;
scanf("%d",&m);
printf("%d\n",time(m));
}
return 0;
}
2042 不容易系列之二
#include<bits/stdc++.h>
int main(){
int n;
scanf("%d",&n);
while(n--){
int a,sum=3;
scanf("%d",&a);
while(a--) sum = (sum-1)*2;
printf("%d\n",sum);
}
return 0;
}
2043 密码
#include<bits/stdc++.h>
int main(){
int n;
scanf("%d",&n);
getchar();
while(n--){
char ch;
int len=0,sign=0,a=0,b=0,c=0,d=0;
int num[127] = {
0};
num[33]=1,num[35]=1,num[36]=1,num[37]=1,num[64]=1,num[94]=1,num[126]=1;
while(scanf("%c",&ch) && ch!='\n'){
len++;
if(65<=ch &&ch<=90 && 0==a) {
sign++;a++;}
else if(97<=ch && ch<=122 && 0==b) {
sign++;b++;}
else if(48<=ch && ch<=57 && 0==c) {
sign++;c++;}
else if(num[(int)ch] && 0==d) {
sign++;d++;}
}
if(sign>=3 && 8<=len && len<=16) printf("YES\n");
else printf("NO\n");
}
return 0;
}
2044 一只小蜜蜂…
还是斐波那契数列。不用递归方法,使用通项公式。
#include<bits/stdc++.h>
double func(int a){
return ( pow((1+pow(5,0.5))/2 ,a) - pow((1-pow(5,0.5))/2 ,a)) / pow(5,0.5);
}
int main(){
int n;
scanf("%d",&n);
while(n--){
int a,b;
scanf("%d %d",&a,&b);
printf("%.0f\n",func(b-a+1));
}
return 0;
}
2045 不容易系列之(3)—— LELE的RPG难题
1格 2格 3格 4格 5格
3 (2)
1 1
2 1
2 (3)
<1> <2>
3 <3>
2 1
1 (3)
2 1
1 (3)
3 1
3 (2)
<1> <2>
2 <3>
3 1
(2)
递推一下:
设 a n a_n an表示共有 n n n个格的时候,所有符合要求的方法数。而 a n 3 \frac{a_n}{3} 3an就是当第一个格子为1的时候的方法数。
手算可以得到 a 1 = 3 , a 2 = 6 , a 3 = 6 , a 4 = 18 a_1=3,a_2=6,a_3=6,a_4=18 a1=3,a2=6,a3=6,a4=18
假设第一个格子是1。对比图中 n = 5 时
a n 3 \frac{a_n}{3} 3an = 前一列中所有非1的个数 + 前一列中所有1的个数的二倍
也就是 a n 3 = a n − 1 3 + ( 2 n − 2 − a n − 1 3 ) ∗ 2 \frac{a_n}{3}=\frac{a_{n-1}}{3}+(2^{n-2}-\frac{a_{n-1}}{3}) *2 3an=3an−1+(2n−2−3an−1)∗2
化简公式,可以得到
a n = 3 ∗ 2 n − 1 − a n − 1 ( n > = 3 ) a_n = 3*2^{n-1}-a_{n-1} (n>=3) an=3∗2n−1−an−1(n>=3)
#include<bits/stdc++.h>
const int max=51;
int main(){
int n;
long long int num[51];
num[1]=3,num[2]=6;
for(int i=3;i<=51;i++){
num[i] = 3*pow(2,i-1)-num[i-1];
}
while(~scanf("%d",&n)){
printf("%lld\n",num[n]);
}
return 0;
}
2046 骨牌铺方格
还是斐波那契数列。
不知道为什么使用递归TLE,还是用公式吧。
#include<bits/stdc++.h>
double func(int a){
return ( pow((1+pow(5,0.5))/2 ,a) - pow((1-pow(5,0.5))/2 ,a)) / pow(5,0.5);
}
int main(){
int n;
while(~scanf("%d",&n)){
printf("%.f\n",func(n+1));
}
return 0;
}
2047 阿牛的EOF牛肉串
递推一下:(注意数据类型,防止溢出)
a n = ( a n − 1 中 以 2 结 尾 的 ) ∗ 2 + ( a n − 1 中 以 1 , 3 结 尾 的 ) ∗ 3 a_n = (a_{n-1}中以2结尾的)*2 + (a_{n-1}中以1,3结尾的)*3 an=(an−1中以2结尾的)∗2+(an−1中以1,3结尾的)∗3
= ( a n − 2 中 以 1 , 3 结 尾 的 ) ∗ 2 + ( a n − 2 ∗ 2 ) ∗ 3 =(a_{n-2}中以1,3结尾的)*2 + (a_{n-2}*2)*3 =(an−2中以1,3结尾的)∗2+(an−2∗2)∗3
= a n − 3 ∗ 2 ∗ 2 + a n − 2 ∗ 6 =a_{n-3}*2*2 + a_{n-2}*6 =an−3∗2∗2+an−2∗6
还找到别人的一种递推:
将所有方法 a n a_n an 分为:以2结尾的 x n x_n xn 和以1,3结尾的 y n y_n yn
a n = x n + y n a_n = x_n+y_n an=xn+yn
= y n − 1 + 2 ∗ a n − 1 =y_{n-1}+2*a_{n-1} =yn−1+2∗an−1
= 2 ∗ a n − 2 + 2 ∗ a n − 1 =2*a_{n-2} + 2*a_{n-1} =2∗an−2+2∗an−1
= 2 ∗ ( a n − 2 + a n − 1 ) =2*(a_{n-2} + a_{n-1}) =2∗(an−2+an−1)
#include<bits/stdc++.h>
long long int time(int n){
if(n==1) return 3;
if(n==2) return 8;
if(n==3) return 22;
return 4*time(n-3)+6*time(n-2);
}
int main(){
int n;
while(~scanf("%d",&n)){
printf("%lld\n",time(n));
}
return 0;
}
2048 神、上帝以及老天爷
错排问题
注意用long long int。
#include<bits/stdc++.h>
long long int time(int n){
if(n==1) return 0;
if(n==2) return 1;
return (n-1)*( time(n-2)+time(n-1) );
}
int main(){
int c;
scanf("%d",&c);
while(c--){
int n;
double all=1;
scanf("%d",&n);
for(int i=2;i<=n;i++){
all *= i;
}
printf("%.2f%%\n",time(n)/all*100);
}
return 0;
}
网上的思路,没有用递推公式
#include<bits/stdc++.h>
int main(){
int c;
scanf("%d",&c);
while(c--){
int n;
scanf("%d",&n);
double all=2,l1=0,l2=0,num=1;
if(n>=2) l1=1;
for(int i=3;i<=n;i++){
num = (i-1)*(l2+l1);
l2 = l1;
l1 = num;
all *= i;
}
printf("%.2f%%\n",num/all*100);
}
return 0;
}
2049 不容易系列之(4)——考新郎
#include<bits/stdc++.h>
long long int time(int n){
if(n==1) return 0;
if(n==2) return 1;
return (n-1)*( time(n-2)+time(n-1) );
}
int main(){
int c;
scanf("%d",&c);
while(c--){
int n,m;
scanf("%d %d",&n,&m);
long long int a=1,b=1,c=1,right=0;
for(int i=1;i<=n;i++){
a *= i;
}
for(int i=1;i<=m;i++){
b *= i;
}
for(int i=1;i<=n-m;i++){
c *= i;
}
right = a/(b*c);
if(m==1) printf("%d\n",n);
else printf("%lld\n",right*time(m));
}
return 0;
}
2050 折线分割平面
#include<bits/stdc++.h>
int main(){
int c;
scanf("%d",&c);
while(c--){
int n;
scanf("%d",&n);
printf("%d\n",2*n*n-n+1);
}
return 0;
}