P2838 瓶子国的故事

题目背景

这是一道非传统题。

传说有一个国家叫瓶子国,里面有大大小小的瓶子。

现在瓶子国想要学习邻居跳蚤国发展计算机,可是瓶子国没有计算机只有瓶子。

于是瓶子国国王就给了你一些瓶子,让你实现一些计算任务。

题目描述

我们用水的量来描述一个数。

  • 一个瓶子的容量为它最多可以装的水的数量。

瓶子国国王认为瓶子可以干这些事:

  • II:制造一个新瓶子,它的容量和里面装的水量都为输入的数,这个瓶子的编号为 当前最大编号+1当前最大编号+1
  • s;把编号为 s 的瓶子里的水倒满。
  • s:把编号为 s 的瓶子里的水倒空。
  • s:制作一个新瓶子,它的容量为 s,里面没装水,这个瓶子的编号为 当前最大编号+1当前最大编号+1。注意由于瓶子容积有限,0≤s≤109
  • s:制作一个新瓶子,它的容量为 s 号瓶子里装的水的数量s 号瓶子里装的水的数量,里面没装水,这个瓶子的编号为 当前最大编号+1当前最大编号+1
  • a b:把 a 瓶往 b 瓶倒水,直到 a 瓶空或者 b 瓶满为止。(注意 a=b)。
  • s:把 s 号瓶子里的水输出。

还有一种昂贵的操作:

  • a b:制作一个新瓶子,它的容量为 a 号瓶子的容量×b 号瓶子的容量a 号瓶子的容量×b 号瓶子的容量,这个瓶子的编号为 当前最大编号+1当前最大编号+1。注意由于瓶子容积有限,a 号瓶子的容量×b 号瓶子的容量a 号瓶子的容量×b 号瓶子的容量,不能超过 109109。(使用这种操作要扣分,评分规则详见下方提示)

现在瓶子国国王把这些操作给了你,你只要输出这些操作,瓶子国的瓶子们就会为你执行!

瓶子国国王给了你一些计算任务,你只需要实现这些任务就行啦!

左边是数据点编号,右边是计算任务。

  1. 输入 a 和 b,计算 �+�a+b。(0≤�,�≤1050≤a,b≤105
  2. 输入 a 和 b,计算 ∣�−�∣∣ab。(0≤�,�≤1050≤a,b≤105
  3. 输入 a 和 b,计算 max⁡(�,�)max(a,b)。(0≤�,�≤1050≤a,b≤105
  4. 输入 a 和 b,输出gcd(a,b)。(1≤a,b≤1000
  5. 输入 a,输出 a 的 3232 位二进制表示。(0≤a≤105,例如 55 输出 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
  6. 输入 a 和 b,输出 a×b。(0≤a,b≤1000
  7. 输入 a 和 b,输出 ab。(0≤a,b≤105⊕⊕ 表示异或)
  8. 输入 a,输出 a÷10 下取整。(1≤a≤10000
  9. 输入 a 和 b,输出 a×bmod262144。(0≤a,b≤105
  10. 输入 a 和 b,输出 a 的 b 次方。(1≤a,b≤1000a 的 b 次方不超过 106106

瓶子国国王会生成 3030 组左右的数据对你的程序进行测试,并根据你使用的操作个数进行评分,评分规则详见下方提示。

代码:

#include <stdio.h>
#include <string.h>
const int N=1002,inf=1e9;
int n,ps,i,j,x,y,z,k,ans,kk;
int a[N],b[N];
inline void I()
{
    printf("I\n");++ps;
}
inline void O(int x)
{
    printf("O %d\n",x);
}
inline void C(int x)
{
    printf("C %d\n",x);++ps;
}
inline void F(int x)
{
    printf("F %d\n",x);
}
inline void E(int x)
{
    printf("E %d\n",x);
}
inline void M(int x)
{
    printf("M %d\n",x);++ps;
}
inline void T(int x,int y)
{
    printf("T %d %d\n",x,y);
}
inline void minmax(int a,int b,int &c,int &d)
{
    M(b);
    T(a,ps);c=ps;
    C(inf);
    T(a,ps);T(b,ps);d=ps;
}
inline void min(int a,int b,int &c)
{
    M(b);
    T(a,ps);c=ps;
}
inline void fb(int x)
{
    M(x);F(ps);T(ps,x);
}
inline void toer(int x,int *a)
{
    M(x);F(ps);
    C(n);
    while (n)
    {
        M(ps-1);x=ps;
        C(n-1);
        T(ps-3,ps-2);
        T(ps-2,ps);
        M(ps-2);
        F(ps);a[20-j]=ps;
        if (n==1) break;
        T(ps-1,ps-3);
        C(1);
        F(ps);
        T(ps,ps-4);C(inf);T(ps-1,ps);z=ps;
        for (i=1;i<=j;i++) fb(z);
        M(z);
        F(x);
        T(x,ps);
        M(x);
        F(ps);
        n>>=1;--j;
        C(n);
    }
}
inline void times(int x,int y,int &z,int l1,int l2,int spe,int nosplit)
{
    int i,k;
    C(inf);
    z=ps;n=l1;j=l2;
    toer(x,a);
    if (!nosplit)
    {
        n=l1;j=l2;toer(y,b);
    }
    for (i=20-l2;i<=20;i++) for (j=20-l2;j<=20;j++) if (i+j>=21)
    {
        if ((spe)&&(40-i-j>=18)) continue;
        M(a[i]);F(ps);
        min(ps,b[j],x);
        C(inf);T(x,ps);x=ps;
        for (k=1;k<=40-i-j;k++) fb(x);
        T(x,z);
    }
}
inline void yfb(int x,int &y)
{
    M(x);F(ps);C(inf);T(x,ps);T(ps-1,ps);y=ps;
}
inline void divide(int w,int x,int &y,int lim,int anj)
{
    int cz;
    int kkk,sc;
    C(inf);y=ps;
    for (i=1;i<=lim;i++)
    {
        C(x);a[i]=ps;
        T(w,ps);if (anj==0) continue;
        M(ps);F(ps);C(x);T(ps-1,ps);C(1);F(ps);T(ps,ps-1);M(ps);F(ps);
        cz=ps;
        for (j=1;j<=7;j++) yfb(cz,cz);
        C(anj);F(ps);
        min(ps,cz,kkk);
        M(kkk);
        T(kkk,y);
    }
    if (x==10) return;
    for (i=1;i<=lim;i++)
    {
        C(x);F(ps);M(a[i]);T(ps-1,ps);M(a[i]);F(ps);
        min(ps-2,ps,kkk);
        for (j=1;j<=8;j++) yfb(kkk,kkk);
        M(kkk);
        T(a[i],ps);T(ps,w);T(a[i],ps);T(ps,w);T(a[i],ps);T(ps,w);T(a[i],ps);T(ps,w);
    }
}
int main()
{
    scanf("%d",&n);
    if (n==10)
    {
        I();I();
        C(1);F(3);y=3;
        C(1);ans=ps;M(1);F(ps);n=524288;j=19;toer(ps,b);
        for (k=1;k<=19;k++)
        {
            times(y,ps,y,524288,19,0,1);
            M(y);x=ps;F(x);
            C(1);T(2,ps);
            C(inf);T(ps-1,ps);z=ps;
            for (i=1;i<=20;i++) fb(z);
            min(x,z,x);
            minmax(x,ans,x,ans);
        }
        O(ans);
        return 0;
    }
    if (n==1)
    {
        I();
        I();
        printf("C 100000000\n");
        printf("T 1 3\n");
        printf("T 2 3\n");
        printf("O 3\n");
        return 0;
    }
    if (n==2)
    {
        I();
        I();
        printf("M 2\n");
        printf("T 1 3\n");
        printf("C 99999999\n");
        printf("T 1 4\n");
        printf("T 2 4\n");
        printf("M 3\n");
        printf("T 4 5\n");
        printf("O 4\n");
        return 0;
    }
    if (n==3)
    {
        I();
        I();
        printf("M 2\n");
        printf("T 1 3\n");
        printf("C 99999999\n");
        printf("T 1 4\n");
        printf("T 2 4\n");
        printf("O 4\n");
        return 0;
    }
    if (n==4)
    {
        n=2;
        I();I();
        for (i=1;i<N;i++)
        {
            printf("M %d\n",n++);
            printf("T %d %d\n",n-2,n);
            printf("C 99999999\n");++n;
            printf("T %d %d\nT %d %d\n",n-3,n,n-2,n);
            printf("M %d\n",n-1);++n;
            printf("T %d %d\n",n-1,n);
            printf("M %d\n",n-1);++n;
            printf("F %d\n",n);
        }
        printf("O %d\n",n);
        return 0;
    }
    if (n==5)
    {
        n=65536;j=16;
        I();
        C(inf);
        for (i=1;i<=15;i++) O(2);
        toer(1,a);
        for (i=4;i<=20;i++) O(a[i]);
        return 0;
    }
    if (n==6)
    {
        I();
        I();
        times(1,2,x,512,9,0,0);
        O(x);
        return 0;
    }
    if (n==7)
    {
        n=65536;j=16;
        I();
        I();
        C(inf);
        toer(1,a);
        n=65536;j=16;
        toer(2,b);
        for (i=4;i<=20;i++)
        {
            minmax(a[i],b[i],x,y);
            M(x);M(y);
            F(ps);T(ps,ps-1);C(inf);T(ps-1,ps);
            z=ps;
            for (j=1;j<=20-i;j++) fb(z);
            M(z);F(ps);T(ps,3);
        }
        O(3);
        return 0;
    }
    if (n==8)
    {
        I();
        divide(1,1000,x,10,100);
        divide(1,100,y,10,10);
        T(y,x);
        divide(1,10,y,10,1);
        T(y,x);
        O(x);
        return 0;
    }
    if (n==9)
    {
        I();I();
        times(1,2,x,65536,16,1,0);
        divide(x,262144,y,100,0);
        O(x);
        return 0;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值