题目链接
下面第一个代码是错误的。
#include
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll ans[100][100];
memset(ans,0,sizeof(ans));
for(int i=2;i<=22;i++)
{
ans[2][i]=1;
ans[i][2]=1;
}
int n,m,c,d;
cin>>n>>m>>c>>d;
for(int i=3;i<=22;i++)
{
for(int j=3;j<=22;j++)
{
ans[c+2][d+2]=ans[c][d+1]=ans[c][d+3]=ans[c+1][d+4]=ans[c+3][d+4]=ans[c+4][d+3]=ans[c+4][d+1]=ans[c+3][d]=ans[c+1][d]=0;
ans[i][j]=ans[i-1][j]+ans[i][j-1];
}
}
cout<
有两个测试数据一直过不去,也不明白是为什么。
思路就是:因为不能碰到马,而且也不能走马的落点,所以,每次计算ans[i][j]的时候,就把那些不能走的地方设置为0,表示无法从那些地方到达当前点。
然后,附上我觉着比较好的一个AC代码:
#include
using namespace std;
int dir[8][2] = {{1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}};
bool d[30][30];
long long dp[30][30];
int main() {
int n, m, cx, cy;
// n, m 是棋盘大小,cx, cy 是马的位置
cin >> n >> m >> cx >> cy;
d[cx][cy]=true;
for(int i=0;i<8;i++){
int tx=cx+dir[i][0];
int ty=cy+dir[i][1];
if(tx>=0&&tx<=n&&ty>=0&&ty<=m){
d[tx][ty]=true;
}
}
dp[0][0]=1;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(d[i][j]==false){
if(i){
dp[i][j]+=dp[i-1][j];
}
if(j){
dp[i][j]+=dp[i][j-1];
}
}
}
}
cout<
上面的代码,在设置马控制的点的那里处理得很好,用了二维数组,不用再一个一个地写。
知道第一个代码为什么出错了,因为,没有考虑到边被马控制的情况,统统把边的初始值设置为了1,所以多加了好多数。
修改后的代码:
#include
#include
using namespace std;
int dir[8][2] = {{1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}};
bool d[30][30];
long long dp[30][30];
int main() {
int n, m, cx, cy;
// n, m 是棋盘大小,cx, cy 是马的位置
cin >> n >> m >> cx >> cy;
d[cx][cy]=true;
for(int i=0;i<8;i++){
int tx=cx+dir[i][0];
int ty=cy+dir[i][1];
if(tx>=0&&tx<=n&&ty>=0&&ty<=m){
d[tx][ty]=true;
}
}
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=20;i++)
{
dp[0][i]=dp[0][i-1];
dp[i][0]=dp[i-1][0];
if(d[0][i]==true) dp[0][i]=0;
if(d[i][0]==true) dp[i][0]=0;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
if(d[i][j]==true) dp[i][j]=0;
}
}
cout<