1314:【例3.6】过河卒(Noip2002)

过河卒

下面是常规的代码,过当然是不能过的

之所以放上来是因为它好歹也是个看的过去的常规搜索递归程序(可惜没找到改成尾递归的方法o(╥﹏╥)o

 1 #include<iostream>
 2 using namespace std;
 3 int n,m,ans,x[9],y[9];
 4 
 5 bool check(int a,int b){
 6     if(a>n||b>m)return 0;
 7     for(int i=0;i<9;i++){
 8         if(a==x[i]&&b==y[i])return 0;
 9     }
10     return 1;
11 }
12 void getPath(int x,int y){
13     if(x==n&&y==m){
14         ans++;
15         return;
16     }
17     if(check(x+1,y))getPath(x+1,y);
18     if(check(x,y+1))getPath(x,y+1);
19 }
20 int main(){
21     
22     cin>>n>>m>>x[0]>>y[0];
23     //得到马所影响的九个位置
24     x[1]=x[4]=x[0]-1,x[2]=x[3]=x[0]-2;
25     x[5]=x[8]=x[0]+1,x[6]=x[7]=x[0]+2;
26     y[1]=y[8]=y[0]+2,y[2]=y[7]=y[0]+1;
27     y[3]=y[6]=y[0]-1,y[4]=y[5]=y[0]-2;
28     //核心算法
29     getPath(0,0);
30     cout<<ans;
31     return 0;
32 }

 下面才是正文,别问,问就是递推≈动态规划

注意下面两点:

  1. 初始化时遇到“断点”应及时break,因为前路断了,后路也不可能有
  2. 最后的结果需要用long long来接收

 


 1 #include<iostream>
 2 using namespace std;
 3 typedef long long ll;
 4 int n,m,x[9],y[9];
 5 ll a[25][25];
 6 
 7 bool check(int a,int b){
 8     for(int i=0;i<9;i++){
 9         if(a==x[i]&&b==y[i])return 0;
10     }
11     return 1;
12 }
13 void init(){
14     x[1]=x[4]=x[0]-1,x[2]=x[3]=x[0]-2;
15     x[5]=x[8]=x[0]+1,x[6]=x[7]=x[0]+2;
16     y[1]=y[8]=y[0]+2,y[2]=y[7]=y[0]+1;
17     y[3]=y[6]=y[0]-1,y[4]=y[5]=y[0]-2;
18     for(int i=0;i<=m;i++)
19         if(check(0,i))a[0][i]=1;
20         else break;
21     for(int i=0;i<=n;i++){
22         if(check(i,0))a[i][0]=1;
23         else break;
24     }
25 }
26 int main(){
27     cin>>n>>m>>x[0]>>y[0];
28     init();
29     for(int i=1;i<=n;i++){
30         for(int j=1;j<=m;j++){
31             if(check(i,j)) a[i][j]=a[i-1][j]+a[i][j-1];
32             else a[i][j]=0;
33         }
34     }
35     cout<<a[n][m];
36     return 0;
37 }

 

posted @ 2021-08-02 21:45  Rekord  阅读(462)  评论(0编辑  收藏  举报