P2239 [NOIP2014 普及组] 螺旋矩阵(CRH-I) · znzryb
## AC代码
本来不是想做这题的,但想不到赛氪竟然连补题都不支持,离谱。
[](https://oj.saikr.com/problem/detail/1854)
这题和赛氪的题还不完全一样,两者螺旋矩阵的顺序有稍许不同
然后比赛的时候不要光想,笔也要动起来,比赛完后我造了个数据6 3 3,结果输出了38,就发现问题了,但赛中没造6的数据。只能说不要停下来呀!!!
[](https://www.luogu.com.cn/record/188066061)
```cpp
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <deque>
#include <cstdio>
#include <cctype>
// https://oj.saikr.com/problem/detail/1854
using namespace std;
typedef long long ll;
const ll N=3010;
ll n,I,J;
// 行号,列号
int main()
{
cin>>n>>I>>J;
ll cen=min(min(I,n+1-I),min(J,n+1-J));
if(cen==(n/2+1)) {
cout<<n*n<<endl;
return 0;
}
ll cnt=0;
for(int i=1;i<cen;++i) {
cnt+=4*(n+2-2*i)-4;
}
for(int j=cen;j<=n+1-cen;++j) { // 从左上走到右上
if(I!=cen) {
cnt+=(n+1-cen)-(cen)+1;
break;
}
++cnt;
if(I==cen && J==j) {
cout<<cnt<<endl;
return 0;
}
}
for(int i=cen+1;i<=n+1-cen;++i) { // 从右上走到右下
if(J!=n+1-cen) {
cnt+=(n+1-cen)-(cen+1)+1;
break;
}
++cnt;
if(I==i && J==n+1-cen) {
cout<<cnt<<endl;
return 0;
}
}
for(int j=n-cen;j>=cen;--j) { // 从右下走到左下
if(I!=n+1-cen) {
cnt+=(n-cen)-(cen)+1;
break;
}
++cnt;
if(I==n+1-cen && J==j) {
cout<<cnt<<endl;
return 0;
}
}
for(int i=n-cen;i>=cen+1;--i) { // 从左下走到左上
if(J!=cen) {
cnt+=(n+1-cen)-cen+1;
break;
}
++cnt;
if(I==i && J==cen) {
cout<<cnt<<endl;
return 0;
}
}
return 0;
}
// AC https://www.luogu.com.cn/record/188066061
```
## 心路历程(WA,TLE,MLE……)
还是声明一下,下面的WA代码不是此题的
主要这段代码出问题了
```cpp
for(int i=1;i<cen;++i) {
cnt+=4*(n+1-i)-4;
}
```
应该写成这样
```cpp
for(int i=1;i<cen;++i) {
cnt+=4*(n+2-2*i)-4;
}
```
这种涉及所有东西推导的代码还是不能够仅靠观察,理性论证也很重要
```cpp
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <deque>
#include <cstdio>
#include <cctype>
using namespace std;
typedef long long ll;
const ll N=3010;
ll n,I,J;
// 行号,列号
int main()
{
cin>>n>>I>>J;
ll cen=min(min(I,n+1-I),min(J,n+1-J));
if(cen==(n/2+1)) {
cout<<n*n<<endl;
return 0;
}
ll cnt=0;
for(int i=1;i<cen;++i) {
cnt+=4*(n+1-i)-4;
}
for(int i=n+1-cen;i>=cen;--i) {
if(J!=cen) {
cnt+=(n+1-cen)-cen+1;
break;
}
++cnt;
if(I==i && J==cen) {
cout<<cnt<<endl;
return 0;
}
}
for(int j=cen+1;j<=n+1-cen;++j) {
if(I!=cen) {
cnt+=(n+1-cen)-(cen+1)+1;
break;
}
++cnt;
if(I==cen && J==j) {
cout<<cnt<<endl;
return 0;
}
}
for(int i=cen+1;i<=n+1-cen;++i) {
if(J!=n+1-cen) {
cnt+=(n+1-cen)-(cen+1)+1;
break;
}
++cnt;
if(I==i && J==n+1-cen) {
cout<<cnt<<endl;
return 0;
}
}
for(int j=n-cen;j>=cen+1;--j) {
if(I!=n+1-cen) {
cnt+=(n+1-cen)-(cen+1)+1;
break;
}
++cnt;
if(I==n+1-cen && J==j) {
cout<<cnt<<endl;
return 0;
}
}
return 0;
}
```
注意!!!TLE不仅代表算法时间复杂度过高,还有可能是死循环(特别是你觉得TLE不可思议时,相信自己的判断,大概率是死循环)
```cpp
for(int j=n+1-cen;j>=cen+1;++j) {
++cnt;
if(I==n+1-cen && J==j) {
cout<<cnt<<endl;
return 0;
}
}
```
像这段代码,是 —j 的,写成了++j,就会死循环TLE
```cpp
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <deque>
#include <cstdio>
#include <cctype>
using namespace std;
typedef long long ll;
const ll N=3010;
ll n,I,J;
// 行号,列号
int main()
{
cin>>n>>I>>J;
ll cen=min(min(I,n+1-I),min(J,n+1-J));
if(cen==(n/2+1)) {
cout<<n*n<<endl;
return 0;
}
ll cnt=0;
for(int i=1;i<cen;++i) {
cnt+=4*(n+1-i)-4;
}
for(int i=n+1-cen;i>=cen;--i) {
++cnt;
if(I==i && J==cen) {
cout<<cnt<<endl;
return 0;
}
}
for(int j=cen+1;j<=n+1-cen;++j) {
++cnt;
if(I==cen && J==j) {
cout<<cnt<<endl;
return 0;
}
}
for(int i=cen+1;i<=n+1-cen;++i) {
++cnt;
if(I==i && J==n+1-cen) {
cout<<cnt<<endl;
return 0;
}
}
for(int j=n+1-cen;j>=cen+1;++j) {
++cnt;
if(I==n+1-cen && J==j) {
cout<<cnt<<endl;
return 0;
}
}
return 0;
}
```