题目:
http://noi.openjudge.cn/ch0207/2987/
模拟;
思路:
离线操作;
记录每一层最后一个数(最大);
然后模拟;
主要步骤:
1.初始化;
2.求出x,y所在层数;
3.蛇形矩阵的模拟;
又丑又长的代码;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=10001;
int n,m;
int a[MAXN],ask[MAXN];
void init()
{
int k=n,cnt=1,sum=0,h;
if(n%2) h=n/2+1;
else h=n/2;
while(cnt<=h)
{
sum+=k*4-4,a[cnt]=sum;
ask[cnt]=k*4-4,k-=2,cnt++;
}
cnt--;
if(n%2) a[cnt]=a[cnt-1]+1;
return;
}
int calc(int x,int y)
{
int k,fx=x,fy=y;
if(n%2)
{
if(fx>n/2+1) fx=abs(fx-n)+1;
if(fy>n/2+1) fy=abs(fy-n)+1;
}
else
{
if(fx>n/2) fx=abs(fx-n)+1;
if(fy>n/2) fy=abs(fy-n)+1;
}
k=min(fx,fy);
int x1,y1,maxn,cnt=0;
if(x==y && n%2 && x==n/2+1) return a[k];
else x1=k+1,y1=k;
maxn=(ask[k]+4)/4;
x1--;
int ans=a[k]-ask[k]+1;
if(x1==x && y1==y) return ans+cnt;
while(y1<k+maxn-1)
{
y1++,cnt++;
if(x1==x && y1==y) return ans+cnt;
}
while(x1<k+maxn-1)
{
x1++,cnt++;
if(x1==x && y1==y) return ans+cnt;
}
while(y1>k)
{
y1--,cnt++;
if(x1==x && y1==y) return ans+cnt;
}
while(x1>k+1)
{
x1--,cnt++;
if(x1==x && y1==y) return ans+cnt;
}
}
void solve()
{
int x,y;
scanf("%d%d",&m,&n);
init();
while(m--)
{
scanf("%d%d",&x,&y);
printf("%d\n",calc(x,y));
}
}
int main()
{
solve();
return 0;
}