c++

P1002 [NOIP2002 普及组] 过河卒

讨论区题解?jbl
by __DIOsama__ @ 2023-07-31 14:18:42


@[DIO__](/user/751866) 我刚交了,楼主的代码是错误的,他应该是 0pts 求调 @[Mark_666](/user/632830) 下次求助标题写清楚一点,不然会误以为是你把题解发在讨论区里,就会被举报。
by sunyizhe @ 2023-07-31 14:40:11


@[sunyizhe](/user/481330) 帮我看看哪里错了,谢
by Mark_666 @ 2023-07-31 16:36:46


@[Mark_666](/user/632830) 目前发现三个问题,改正后 40 分: 1. 你的坐标每个都要 $+1$,因为题目中的 $x,y$ 坐标是从 $0$ 行 $0$ 列开始算起的。 2. $a$ 数组要开 `long long`,不然测试点 $3$ 你输出了一个负号在开头,说明 `int` 类型溢出了。 3. for 循环初始化列的时候,你的循环条件应该是 `i<=m` 而不是 `i<=n`,不然第五个测试点 WA。
by sunyizhe @ 2023-08-01 15:51:37


@[Mark_666](/user/632830) 找到核心原因了:第一行和第一列也有可能被马占据,所以初始化时要判断当前位置是不是被马占据,如果没有再赋值 $1$。
by sunyizhe @ 2023-08-01 16:13:52


```cpp #include<bits/stdc++.h> using namespace std; int fx[8]={ -2, -1, 1, 2, 2, 1, -1, -2}; int fy[8]={ 1, 2, 2, 1, -1, -2, -2, -1}; int hox[8]; int hoy[8]; long long a[100][100]; int n,m,hx,hy; int main() { cin>>n>>m>>hx>>hy; for(int i=0;i<=n;i++) a[i][0]=1; for(int i=0;i<=m;i++) a[0][i]=1; for(int i=0;i<8;i++) { hox[i]=fx[i]+hx; hoy[i]=fy[i]+hy; if(hox[i]<0||hoy[i]<0||hox[i]>n||hoy[i]>m) continue; a[hox[i]][hoy[i]]=0; } a[hx][hy]=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { bool pd=true; for(int k=0;k<8;k++) if(i==hox[k]&&j==hoy[k]) pd=false; if(i==hx&&j==hy) pd=false; if(pd) a[i][j]=a[i-1][j]+a[i][j-1]; } } for(int i=0;i<=n;i++) { for(int j=0;j<=m;j++) { cout<<a[i][j]<<' '; } cout<<endl; } cout<<a[n][m]<<endl; return 0; } ``` @[sunyizhe](/user/481330) 改了不少,样例对了,但是全部WA。。。。
by Mark_666 @ 2023-08-01 17:00:07


@[Mark_666](/user/632830) 疯狂改 ing…… ```cpp //60分代码:WA 测试点3,4 #include<bits/stdc++.h> using namespace std; //#define int long long int fx[9]={0, 2, 1, -1, -2, -2, -1, 1 , 2}; int fy[9]={0, 1, 2, 2 , 1 , -1, -2, -2, -1}; int hox[9],hoy[9]; long long a[510][510]; int n,m,hx,hy; int main() { cin>>n>>m>>hx>>hy; n++,m++,hx++,hy++; for(int i=0;i<9;i++) { hox[i]=fx[i]+hx; hoy[i]=fy[i]+hy; if(hox[i]<1||hox[i]>n)hox[i]=n+10,hoy[i]=m+10; if(hoy[i]<1||hoy[i]>m)hox[i]=n+10,hoy[i]=m+10; //cout<<hox[i]<<' '<<hoy[i]<<endl; } //cout<<endl; //cout<<(!(hox[0]==5&&hoy[0]==1)) // for(int i=0;i<9;i++) // cout<<hox[i]<<' '<<hoy[i]<<endl; for(int i=1;i<=n;i++) { bool flag=true; for(int j=0;j<9;j++) { if((hox[j]==i&&hoy[j]==1)) { flag=false; break; } if(flag)a[i][1]=1LL; //if(i==5&&hoy[j]==1&&hox[j]==5)cout<<"1---------------"<<endl<<endl; } } for(int i=1;i<=m;i++) { bool flag=true; for(int j=0;j<9;j++) { if((hoy[j]==i&&hox[j]==1)) { flag=false; break; } //if(i==5&&hox[j]==1&&hoy[j]==5)cout<<1<<' '<<i<<a[1][i]<<' '<<endl<<endl; } if(flag)a[1][i]=1LL; } // cout<<a[1][5]<<endl<<endl; // for(int i=1;i<=n;i++) // { // for(int j=1;j<=m;j++) // cout<<a[i][j]<<' '; // cout<<endl; // } // for(int i=2;i<=n;i++) { for(int j=2;j<=m;j++) { bool pd=true; for(int k=0;k<9;k++) if(i==hox[k]&&j==hoy[k]) pd=false; //if(i==hx&&j==hy) pd=false; if(pd) a[i][j]=a[i-1][j]+a[i][j-1]; } } cout<<a[n][m]<<endl; return 0; } ```
by sunyizhe @ 2023-08-01 17:57:46


@[Mark_666](/user/632830) ~~这下好了,一个人的代码求调变成两人一起求调了~~
by sunyizhe @ 2023-08-01 17:58:27


@[Mark_666](/user/632830) 你的代码是不是忘注释最下面输出 $a$ 数组的代码了,你的代码跟我一样 60 分 ![](//图.tk/7)
by sunyizhe @ 2023-08-01 18:00:29


@[Mark_666](/user/632830) 我还是不按照你的代码改了,自己写一个吧,不然一直改太乱了,你看一下,我带注释: ```cpp #include<bits/stdc++.h> using namespace std; //#define int long long // 1 1 1 1 1 1 1 1 const int fx[9]={0, 2, 1, -1, -2, -2, -1, 1 , 2}; const int fy[9]={0, 1, 2, 2 , 1 , -1, -2, -2, -1}; int hox[9],hoy[9]; long long a[1010][1010]; bool vis[1010][1010]; int n,m,hx,hy; int main() { cin>>n>>m>>hx>>hy; n++,m++,hx++,hy++; //计算hox[i]并标记 for(int i=0;i<9;i++) { hox[i]=hx+fx[i]; hoy[i]=hy+fy[i]; //若马坐标越界,就改成自身 if(hox[i]<0||hox[i]>n||hoy[i]<0||hoy[i]>m)hox[i]=hx,hoy[i]=hy; vis[hox[i]][hoy[i]]=true; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { //先判断是否有马的坐标,在判断是否i==1&&j==1,最后将左边和上面的值加起来 if(vis[i][j])a[i][j]=0; else if(i==1&&j==1)a[i][j]=1; else a[i][j]=a[i-1][j]+a[i][j-1]; } cout<<a[n][m]<<endl; return 0; } ``` AC 啦!
by sunyizhe @ 2023-08-01 18:26:54


|