有2×n的一个长方形方格,用一个1×2的骨牌铺满方格。
例如n=3时,为2×3方格。此时用一个1×2的骨牌铺满方格,共有如下3种铺法:
试对给出的任意一个n(0<n<90),求出铺法总数。
输入/输出例子1
输入:2
输出:2
#include<bits/stdc++.h>
using namespace std;
long long n,a[95];
int main(){
cin>>n;
a[1]=1,a[2]=2;
for(int i=3;i<=n;i++)
{
a[i]=a[i-1]+a[i-2];
}
cout<<a[n];
return 0;
}
一天,晨晨的数学老师布置了一道题目,大意如下:用1*1和2*2的瓷砖不重叠地铺满n*3的地板,共有多少种方案?
例如:
n=1时:1*3的地板方法就一个,直接由三个的瓷砖铺满。
n=2时:2*3的地板可以由下面3种方案铺满:
输入格式
第一行:一个整数n(1<=n<=50)
输出格式
输出铺满n*3的地板的方案数
输入/输出例子1
输入:
3
输出:
5
样例解释
数据范围
对于20%的数据,1<=n<=15;
对于50%的数据,1<=n<=30;
对于100%的数据,1<=n<=50;
#include<bits/stdc++.h>
using namespace std;
long long f[55],n;
int main(){
cin>>n;
f[1]=1,f[2]=3;
for(int i=3;i<=n;i++)
{
f[i]=2*f[i-2]+f[i-1];
}
cout<<f[n];
return 0;
}
一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:
蜜蜂从蜂房M开始爬到蜂房N,1<=M< N<=50,有多少种爬行路线?
输入格式
输入M,N的值。
输出格式
爬行有多少种路线。
输入/输出例子1
输入:
1 14
输出:
377
#include<bits/stdc++.h>
using namespace std;
long long n,m,a[55];
int main(){
cin>>m>>n;
n=n-m+1;
a[1]=1,a[2]=1;
for(int i=3;i<=n;i++)
{
a[i]=a[i-1]+a[i-2];
}
cout<<a[n];
return 0;
}
为了迎接2008年鼠年的到来,老鼠王国举行了盛大的游园活动,其中有一个叫"走迷宫"的活动,老鼠在八边形的蜂状迷宫(如下图)里可以向下、向右、斜向上、斜向下爬行到相邻的蜂房中去,不能反向爬行。当然,蜂房里还有一只猫,有猫的蜂房老鼠是不敢进去的,只能绕过。试求老鼠从蜂房1爬到蜂房N所有可能路线的总数。
输入格式
共2行,第1行1个整数N(1<=N<=100),表示老鼠要达到的蜂房,第2行1个整数M(M<=N),表示猫在蜂房的位置。
输出格式
一个整数S,表示老鼠从蜂房1爬到蜂房N所有可能路线的总数,如果不能达到,则输出0。答案可能很大。
输入/输出例子1
输入:
4
2
输出:
2
#include<bits/stdc++.h>
using namespace std;
long long f[105],n,m;
int main(){
cin>>n>>m;
if(m==1||m==1)
{
cout<<0;
return 0;
}
f[1]=1;
for(int i=2;i<=n;i++)
{
if(i==m) continue;
if(i%2==0) f[i]=f[i-1]+f[i-2]+f[i-3];
else f[i]=f[i-1]+f[i-2];
}
cout<<f[n];
return 0;
}
棋盘上A点有一个过河卒,需要走到目标点。卒行走的规则:可以向下、或者向右。那么从点(0,0)开始,每次只能向下走一步或者向右走一步,到达点(x,y)有多少种不同的走法?
输入格式
两个整数,即x和y。 0 <= x, y < = 10。
输出格式
一个整数,不同的走法的数量。
输入/输出例子1
输入:
1 1
输出:
2
#include<bits/stdc++.h>
using namespace std;
int a[15][15],n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
a[i][0]=1;
for(int i=1;i<=m;i++)
a[0][i]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
a[i][j]=a[i-1][j]+a[i][j-1];
}
cout<<a[n][m];
return 0;
}
设有一个N*M(1<=N<=50,1<=M<=50)的街道,规定行人从A(1,1)出发,在街道上只能向东或北行走。
若在此街道中,设置一个矩形障碍区域(包括围住该区域的的街道)不让行人通行,如上图中用“*”表示的部分。此矩形障碍区域用2对顶点坐标给出,如上图中的2对顶点坐标为(2,2),(8,4),此时从A出发到达B的路径有两条。
现给出N、M,同时再给出此街道中的矩形障碍区域的2对顶点坐标(x1,y1),(x2,y2),请求出此时所有从A出发到达B的路径的条数。
输入格式
第一行输入n,m
第二行分别输入对应障碍的定点坐标x1,y1,x2,y2
输出格式
一行,即所有从A出发到达B的路径的条数
输入/输出例子1
输入:
9 5
2 2 8 4
输出:
2
#include<cstdio>
#include<algorithm>
#define maxn 60
#define l 10000000000
using namespace std;
struct number{
long long d1,d2;
}f[maxn][maxn];
int n,m;
int flag[maxn][maxn];
void start(){
long long s;
f[1][1].d1=1;f[1][1].d2=0;
for(int k=3;k<=m+n;k++)
for(int i=1;i<=n;i++){
if(k-i>=1&&k-i<=m&&!flag[i][k-i]){
int j=k-i;
if(j-1>=1) f[i][j]=f[i][j-1];
if(i-1>=1){
s=f[i][j].d1+f[i-1][j].d1;
f[i][j].d1=s%l;
f[i][j].d2=(f[i-1][j].d2+f[i][j].d2+s/l)%l;
}
}
}
if(f[n][m].d2==0) printf("%I64d\n",f[n][m].d1);
else printf("%I64d%010I64d\n",f[n][m].d2,f[n][m].d1);
}
int main(){
int x1,x2,y1,y2;
scanf("%d%d",&n,&m);
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1>x2) swap(x1,x2);
if(y1>y2) swap(y1,y2);
for(int i=x1;i<=x2;i++)
for(int j=y1;j<=y2;j++)
flag[i][j]=1;
start();
return 0;
}
- 附加题
第1题 马拦过河卒(noip2002pj4)棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个数据,分别表示B点坐标和马的坐标。
输出格式
一个数据,表示所有的路径条数。
输入/输出例子1
输入:
6 6 3 2
输出:
17
#include<bits/stdc++.h> using namespace std; int n,m,x,y,c=0; int s[205][205]; int dx[9]={0,-2,-1,1,2,2,1,-1,-2}; int dy[9]={0,1,2,2,1,-1,-2,-2,-1}; void search(int x,int y){ if(x==n&&y==m) c+=1; if(y<=m&&s[x][y+1]==0) search(x,y+1); if(x<=n&&s[x+1][y]==0) search(x+1,y); } int main(){ scanf("%d%d%d%d",&n,&m,&x,&y); s[x][y]=1; for(int i=1;i<=8;i++){ int xx=x+dx[i],yy=y+dy[i]; if(xx>=0&&xx<=n&&yy>=0&&yy<=m) s[xx][yy]=1; } search(0,0); printf("%d",c); return 0; }
第2题 骑士游历问题(knight)设有一个 n×m 的棋盘(2 ≤ n ≤ 50,2 ≤ m ≤ 50),在棋盘上任一点有一个中国象棋“马”,马走的规则为:马走日字;马只能向右走。当 n,m 给出后,同时给出马起始的位置和终点的位置,试找出从起点到终点所有路径的数目。
输入格式
n,m,x1,y1,x2,y2 (分别表示棋盘大小、起点坐标和终点坐标)。
输出格式
路径数目(若不存在,则输出0)
输入/输出例子1
输入:
30 30 1 15 5 15
输出:
8
#include<bits/stdc++.h> using namespace std; long long n,m,x, y, xx, yy, a[55][55]; bool f(int x,int y) { if(x>=1 && x <= n && y>=1 && y <= m) return 1; return 0; } int main() { cin>>n>>m>>x>>y>>xx>>yy; swap(n,m);swap(x,y);swap(xx,yy); a[x][y]=1; for(int j=y+1;j <= yy;j++) for(int i=1;i <= n;i++) { if(f(i-2,j-1)) a[i][j]+=a[i-2][j-1]; if(f(i-1,j-2)) a[i][j]+=a[i-1][j-2]; if(f(i+1,j-2)) a[i][j]+=a[i+1][j-2]; if(f(i+2, j-1)) a[i][j]+=a[i+2][j-1]; } cout <<a[xx][yy]; return 0; }