[openjudge2987]小兔子捡金币

题目←

头一次打那么长的代码re了一遍就过了!(哭)

唔……略微的眼熟,跟清北学堂那天的模拟有点像?
总之找规律吧……找找找找……
等等为什么代码这么长?
是不是处理了很多没用的东西?算了不管了……

#include<iostream>
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
const LL MAXN = 100000 + 50;
struct zt
{
    LL l,r;
}lim[MAXN];
struct zt2
{
    LL u,d;
}h[MAXN];
LL n,L[MAXN],R[MAXN];
LL U[MAXN],D[MAXN];
LL find(LL x,LL y)
{
    if(x <= n/2)
    {
        if(y >= lim[x].l && y <= lim[x].r)
        {
            return L[x] + (y - lim[x].l);
        }
        else if(y < lim[x].l)
        {
            return U[y] - (x - h[y].u);
        }
        else if(y > lim[x].r)
        {
            return U[y] + (x - h[y].u);
        }
    }
    else
    {
        if(y >= lim[x].l && y <= lim[x].r)
        {
            return L[x] - (y - lim[x].l);
        }
        else if(y < lim[x].l)
        {
            return U[y] + (h[y].u - x);
        }
        else if(y > lim[x].r)
        {
            return U[y] - (h[y].u - x);
        }
    }
}
LL k;
int main()
{
    scanf("%lld%lld",&k,&n);
    LL tmp = 0;
    for(LL i = 1;i <= n/2;i ++)
    {
        lim[i].l = 1 + tmp;
        lim[i].r = n - tmp;
        tmp ++;
    }
    if(n % 2)
    {
        lim[n/2 + 1].l = n/2 + 1;
        lim[n/2 + 1].r = n/2 + 1;
    }
    tmp = 0;
    for(LL i = n;i > n - n/2;i --)
    {
        lim[i].l = 1 + tmp;
        lim[i].r = n - tmp;
        tmp ++;
    }
    tmp = n - 1;
    LL pre1 = 1,pre2 = n;
    L[1] = pre1;R[1] = pre2;
    LL temp = 1;
    U[1] = L[1] + 3 * (n - temp) + n - temp - 1;
    U[n] = R[1];
    temp += 2;
    for(LL i = 2;i <= n/2;i ++)
    {
        L[i] = pre1 + 4 * tmp;
        R[i] = pre2 + 4 * tmp - 2;
        U[i] = L[i] + 3 * (n - temp) + n - temp - 1;
        U[n - i + 1] = R[i];
        pre1 = L[i];
        pre2 = R[i];
        tmp -= 2;
        temp += 2;
    }
    if(n%2)
    {
        L[n/2 + 1] = n*n;
        R[n/2 + 1] = n*n;
        U[n/2 + 1] = n*n;
        D[n/2 + 1] = n*n;
    }
    pre1 = 1 + 3 * (n - 1);pre2 = 1 + 2 * (n - 1);
    LL tmp1 = 2;
    LL tmp2 = 3;
    L[n] = pre1;R[n] = pre2;
    D[n] = L[n];
    for(LL i = n - 1;i > n - n/2;i --)
    {
        L[i] = pre1 + (n - tmp1) * 2 + (n - tmp2) * 2;
        R[i] = L[i] - (n - (n - i) * 2) + 1;
        D[n - i + 1] = L[i];
        D[i] = R[i];
        pre1 = L[i];
        pre2 = R[i];
        tmp1 += 2;
        tmp2 += 2;
    }
    tmp = 0;
    for(LL i = 1;i <= n/2;i ++)
    {
        h[i].u = 1 + tmp + 1;
        h[i].d = n - tmp;
        tmp ++;
    }
    if(n % 2)
    {
        h[n/2 + 1].u = n/2 + 1;
        h[n/2 + 1].d = n/2 + 1;
    }
    tmp = 0;
    for(LL i = n;i > n - n/2;i --)
    {
        h[i].u = 1 + tmp;
        h[i].d = n - tmp;
        tmp ++;
    }
    LL a,b;
    for(LL i = 1;i <= k;i ++)
    {
        scanf("%lld%lld",&a,&b);
        printf("%lld\n",find(a,b));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值