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:
|
|
|
| ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
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 2 2 10 | 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);
}
}