F. Letter Grid 动态规划问题

F.         Letter Grid

Consider the following letter grid:

E     

R    

A    

T      

A

T

S

R

A

U

T

U

There are 7 ways to read the word TARTU fromthe grid:

E   

R   

A   

T   

A

T

S

R

A

U

T

U

E     

R     

A    

T   

A

T

S

R

A

U

T

U

E     

R     

A    

T     

A

T

S

R

A

U

T

U

E    

R    

A    

T      

A

T

S

R

A

U

T

U

E     

R   

A  

T  

A

T

S

R

A

U

T

U

E    

R     

A   

T    

A

T

S

R

A

U

T

U

E   

R    

A   

T    

A

T

S

R

A

U

T

U

 

Given a letter grid and a word, your task isto determine the number of ways the word can be read from the grid. The firstletter of the word can be in any cell of the grid, and after each letter, thenext letter has to be in one of the neighbour cells (horizontally, verticallyor diagonally). A cell can be used multiple times when reading the word.

Input Data

Each test case contains three integers: H(1 ≤ H ≤ 200), the height of the grid,W(1 ≤ W ≤ 200), the width of the grid, andL(1 ≤ L ≤ 100), the length of the word. The followingHlines each containingW letters describe the grid. The lastline containingL letters describes the word. All letters in the grid andin the word are uppercase English letters (A...Z).

Output Data

For each case, output only line contained oneinteger: the number of ways the word can be read from the grid. You may assumethat the answer is always at most 1018.

Examples

in

out

3 4 5                         
ERAT
ATSR
AUTU
TARTU

2 2 10
AA
AA
AAAAAAAAAA

7                

78732

只有zzy队长一个人a出了这道题,膜拜队长中~~典型的dp问题 来求解

算法: 

拿第一个举一个例子 

ERAT 搜第一个T  0001    搜第二个A时 对A所在位置周边8个数相加得到  0020         例如 第一个A在(0,2)位置上,周边8个位上有(0,3)(1,1)上有值为1,相加得到2.
ATSR                  0100                                                                       1000
AUTU                  0010                                                                       1000

搜R时    0300   搜T时 0002    搜U时 0000      在搜u结束后总共有5+2 7个结果

             0002            0300              0000

             0000            0020              0502


#include<stdio.h>
char a[210][210];
__int64 b[210][210];
__int64 c[210][210];
__int64 sum=0;
char judge[200];
int x[9]={0,-1,-1,-1,0,0,1,1,1};
int y[9]={0,-1,0,1,-1,1,-1,0,1};
int main()
{
  int wid,hit,len,i,j,ji,k,xa,ya;
  while(scanf("%d %d %d",&wid,&hit,&len)!=EOF)
  {
     ji=0;
     for(i=0;i<wid;i++)    
       scanf("%s",a[i]);              
     scanf("%s",judge);     
     for(i=0;i<wid;i++)
      for(j=0;j<hit;j++)    //寻找 judge[0]的值,、 
        {
        if(a[i][j]==judge[ji])b[i][j]=1;
        else b[i][j]=0;   
        }
      if(len==1){                  //会出现长度为1的这种特殊情况
                 sum=0;
                 for(i=0;i<wid;i++)
                   for(j=0;j<hit;j++)
                     sum+=b[i][j];
                 printf("%I64d\n",sum);
                 continue;
                 }  

  while(ji!=len-1)            //用长度来表示循环的次数,
   { 
        ji++;
        
     for(i=0;i<wid;i++)                     //两个数组分别记录 dp的数据
      for(j=0;j<hit;j++)
      {
        if(a[i][j]==judge[ji]){
         sum=0;
         for(k=1;k<9;k++)
           {   
           int xa=i+x[k];     //注意这里应当重新定义xa,ya来进行带入,如不重新定义后面的值会影响xa,ya的结果 
           int ya=j+y[k];
           if(xa>=0&&xa<wid&&ya>=0&&ya<hit)
            {if(b[xa][ya]!=0)
              {
                sum+=b[xa][ya];
              }
            }
           }

              c[i][j]=sum;               
                             }
         else c[i][j]=0;              
      }

     for(i=0;i<wid;i++)                  //将数据进行拷贝
       {
       for(j=0;j<hit;j++)
         {
         b[i][j]=c[i][j];
         }
       }   
   }
           sum=0;                   //输出结果
        for(i=0;i<wid;i++)
          for(j=0;j<hit;j++)
              sum+=b[i][j];
         printf("%I64d\n",sum);
 
   
   
  
}   
    
}





评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值