【省选组】模拟 jzoj.3993 乾坤大挪移

 

 

这题很容易可以转换模型,把操作一转换为纵坐标改变一个小于2*(l-1)的偶数的值,操作二转换为横纵坐标同时改变一个小于(l-1)的值。

然后贪心处理。

容易想到操作二最多进行一次,所以只要枚举是否进行操作二然后取最大值就可以了。

有一个问题要注意,当操作二改变的值为(l-2)时,可能要再次改变一次(l-1)答案最优,此时可以转换为向右上角走一步然后用操作一走,步数都是两步。

然后就是高精度除法的问题。

可以考虑二分商然后判断。

但是因为这题卡了时间,所以没过。

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define mo 1000000000
#pragma GCC optimize(3)
#define N 80
using namespace std;
ll T,i,bzp,p[N*10],len,sum,lp,mi[20];
char ch[N];
ll div(ll x,ll y){
    if (x%y==0) return x/y;
    return x/y+1;
}
struct bignum{
    ll x[N],len;
}n,m,l,ans,ans1,temp,mx,L,R,mid,ansp,l2,l_1;
ll pd(bignum a,bignum b){
    ll i;
    if (a.len<b.len) return 1;
    if (a.len>b.len) return 0;
    for (i=a.len;i>=1;i--){
        if (a.x[i]<b.x[i]) return 1;
        if (a.x[i]>b.x[i]) return 0;
    }
    return 0;
}
void swap1(bignum &a,bignum &b){
    temp=a;
    a=b;
    b=temp;
}
bignum add(bignum a,bignum b){
    ll i;
    if (pd(a,b))
        swap1(a,b);
    for (i=1;i<=a.len;i++){
        a.x[i]+=b.x[i];
        a.x[i+1]+=a.x[i]/mo;
        a.x[i]%=mo;
    }
    while (a.x[a.len+1]) a.len++;
    return a;
}
bignum add1(bignum a,ll b){
    ll k=1;
    a.x[1]+=b;
    while (a.x[k]>=mo){
        a.x[k+1]+=a.x[k]/mo;
        a.x[k]%=mo;
        k++;
    }
    while (a.x[a.len+1]) a.len++;
    return a;
}
bignum sub(bignum a,bignum b){
    ll i;
    for (i=1;i<=a.len;i++){
        a.x[i]-=b.x[i];
        if (a.x[i]<0) a.x[i]+=mo,a.x[i+1]--;
    }
    while (a.x[a.len]==0) a.len--;
    return a;
}
bignum sub1(bignum a,ll b){
    ll k=1;
    a.x[1]-=b;
    while (a.x[k]<0){
        a.x[k]+=mo;
        a.x[k+1]--;
        k++;
    }
    while (a.x[a.len]==0) a.len--;
    return a;
}
ll mod(bignum a,ll k){
    return a.x[1]%k;
}
void write(bignum a){
    ll i,j,n,x;
    printf("%lld",a.x[a.len]);
    for (i=a.len-1;i>=1;i--){
        x=a.x[i];
        n=0;
        while (x){
            n++;
            x/=10;
        }
        for (j=1;j<=9-n;j++) printf("0");
        printf("%lld",a.x[i]);
    }
    printf("\n");
}
bignum mul(bignum a,bignum b){
    ll i,j;
    for (i=0;i<=temp.len;i++)
        temp.x[i]=0;
    temp.len=a.len+b.len-1;
    for (i=1;i<=a.len;i++){
        for (j=1;j<=b.len;j++){
            temp.x[i+j-1]+=a.x[i]*b.x[j];
            temp.x[i+j]+=temp.x[i+j-1]/mo;
            temp.x[i+j-1]%=mo;
        }
    }
    while (temp.x[temp.len+1]) temp.len++;
    return temp;
}
bignum div1(bignum a,ll b){
    ll i,r=0;
    for (i=a.len;i>=1;i--){
        r=r*mo+a.x[i];
        a.x[i]=r/b;
        r=r%b;
    }
    while (a.x[a.len]==0) a.len--;
    return a;
}
bignum div(bignum a,bignum b){
    ll i;
    for (i=0;i<=L.len;i++)
        L.x[i]=0;
    for (i=0;i<=ansp.len;i++)
        ansp.x[i]=0;
    L.len=1;L.x[1]=1;
    R=a;
    while (pd(R,L)==0){
        mid=div1(add(L,R),2);
        if (pd(mul(mid,b),a))
            L=add1(mid,1);
        else{
            R=sub1(mid,1);
            ansp=mid;
        }
    }
    return ansp;
}
int main(){
    freopen("move.in","r",stdin);
    freopen("move.out","w",stdout);
    scanf("%lld",&T);
    mx.len=N-1;
    for (i=1;i<N;i++)
        mx.x[i]=mo-1;
    mi[0]=1;
    for (i=1;i<=10;i++)
        mi[i]=mi[i-1]*10;
    while (T--){
        memset(n.x,0,sizeof(n.x));
        memset(m.x,0,sizeof(m.x));
        memset(l.x,0,sizeof(l.x));
        n.len=m.len=l.len=0;
        scanf("%s",ch+1);
        bzp=0;
        if (ch[1]=='-') bzp=1;
        len=strlen(ch+1)-bzp;
        for (i=bzp+1;i<=strlen(ch+1);i++)
            if (ch[i]!='-')
                p[i-bzp]=ch[strlen(ch+1)-i+1+bzp]-'0';
        sum=0;
        lp=0;
        for (i=1;i<=len;i++){
            lp++;
            sum=p[i]*mi[lp-1]+sum;
            if (lp==9){
                n.len++;
                n.x[n.len]=sum;
                lp=0;
                sum=0;
            }
        }
        if (lp){
            n.len++;
            n.x[n.len]=sum;
        }
        
        scanf("%s",ch+1);
        bzp=0;
        if (ch[1]=='-') bzp=1;
        len=strlen(ch+1)-bzp;
        for (i=bzp+1;i<=strlen(ch+1);i++)
            if (ch[i]!='-')
                p[i-bzp]=ch[strlen(ch+1)-i+1+bzp]-'0';
        sum=0;
        lp=0;
        for (i=1;i<=len;i++){
            lp++;
            sum=p[i]*mi[lp-1]+sum;
            if (lp==9){
                m.len++;
                m.x[m.len]=sum;
                lp=0;
                sum=0;
            }
        }
        if (lp){
            m.len++;
            m.x[m.len]=sum;
        }
        
        scanf("%s",ch+1);
        bzp=0;
        if (ch[1]=='-') bzp=1;
        len=strlen(ch+1)-bzp;
        for (i=bzp+1;i<=strlen(ch+1);i++)
            if (ch[i]!='-')
                p[i-bzp]=ch[strlen(ch+1)-i+1+bzp]-'0';
        sum=0;
        lp=0;
        for (i=1;i<=len;i++){
            lp++;
            sum=p[i]*mi[lp-1]+sum;
            if (lp==9){
                l.len++;
                l.x[l.len]=sum;
                lp=0;
                sum=0;
            }
        }
        if (lp){
            l.len++;
            l.x[l.len]=sum;
        }
        if (pd(n,m))
            swap1(n,m);
        if (mod(n,2)!=mod(m,2)){
            printf("Poor MLG!\n");
            continue;
        }
        ans=ans1=mx;
        l=sub1(l,1);
        l2=add(l,l);
        l_1=sub1(l,1);
        if (pd(l,m)==0){
            ans=add1(div(sub(n,m),l2),1);
            write(ans);
            continue;
        }
        if (mod(n,2)==1){
            if (pd(m,add(l,sub1(l,1)))==0)
                ans1=add(div(add1(n,1),l2),div(add1(m,1),l2));
            if (mod(l,2)==1)
                ans=add1(add(div(sub(n,l),l2),div(sub(m,l),l2)),1);
            else
                ans=add1(add(div(sub(n,l_1),l2),div(sub(m,l_1),l2)),1);
        }
        else{
            ans1=add(div(n,l2),div(m,l2));
            if (mod(l,2)==0)
                ans=add1(add(div(sub(n,l),l2),div(sub(m,l),l2)),1);
            else
                ans=add1(add(div(sub(n,l_1),l2),div(sub(m,l_1),l2)),1);
            //write(sub(n,l));write(l2);
            //write(div(sub(n,l),l2));
        }
        if (pd(ans1,ans))
            write(ans1);
        else
            write(ans);
    }
    return 0;
}

 

 

 

posted @ 2020-09-23 22:17  Mohogany  阅读(117)  评论(0编辑  收藏  举报