2010-1090

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

题目大意是对一个立方体有6种操作,fill、query、find和3种swap。因为每次query、find和swap的范围都不超过fill的范围,因此可以把每次fill看作不同case的分界

当没有swap操作时,立方体(i,j,k)坐标对应的值是 YZ*i+Z*j+k+1,同理可以算出一个值C对应的座标(i,j,k)为k=C-1 mod Z,j=(C-1)/Z mod Y,;i=(C-1)/Z/Y。

因为3种swap是分别对不同维度的操作,因此不会相互影响,只要用3个一维数组记录该位置实际存放的点(对应query操作),再用3个一维数组记录该位置原来点的当前位置( 对应find操作)。

{{{
#!cpp
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int x,y,z,r,t;
int sw[3][1011];  //我这里的代码是用在前三个数组中搜索的方法来实现后三个数组的功能,因此只用了前3个数组
void swap(int d,int a,int b)
{
    int t=sw[d][a];
    sw[d][a]=sw[d][b];
    sw[d][b]=t;
}
int main()
{
    int i,j,k,cnt,t;
    char s[10];
    while (scanf("%s",s)!=EOF)
    {
        if (s[2]=='L')
        {
            scanf("%d%d%d",&x,&y,&z);
            printf("START\n");
            for (i=0;i<3;i++)
                for (j=0;j<1000;j++)
                    sw[i][j]=j;
        }
        if (s[0]=='S')
        {
            scanf("%d%d",&r,&t);
            int kk=s[4]-'1';
            swap(kk,r,t);
        }
        if (s[2]=='N')
        {
            scanf("%d",&cnt);
            if (cnt>x*y*z) continue;
            cnt-=1;
            k=cnt%z;
            cnt/=z;
            j=cnt%y;
            cnt/=y;
            i=cnt;
            for (t=0;t<x;t++)
                if (sw[0][t]==i)
                {
                    i=t; break;
                }
            for (t=0;t<y;t++)
                if (sw[1][t]==j)
                {
                    j=t; break;
                }
            for (t=0;t<z;t++)
                if (sw[2][t]==k)
                {
                    k=t; break;
                }
            printf("%d %d %d\n",i,j,k);
        }
        if (s[0]=='Q')
        {
            scanf("%d%d%d",&i,&j,&k);
            i=sw[0][i];
            j=sw[1][j];
            k=sw[2][k];
            cnt=(i*y+j)*z+k;
            printf("%d\n",cnt+1);
        }
    }
    return 0;
}       
}}}
by pxhdg

题目大意是对一个立方体有6种操作,fill、query、find和3种swap。因为每次query、find和swap的范围都不超过fill的范围,因此可以把每次fill看作不同case的分界

当没有swap操作时,立方体(i,j,k)坐标对应的值是 YZ*i+Z*j+k+1,同理可以算出一个值C对应的座标(i,j,k)为k=C-1 mod Z,j=(C-1)/Z mod Y,;i=(C-1)/Z/Y。

因为3种swap是分别对不同维度的操作,因此不会相互影响,只要用3个一维数组记录该位置实际存放的点(对应query操作),再用3个一维数组记录该位置原来点的当前位置( 对应find操作)。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int x,y,z,r,t;
int sw[3][1011];  //我这里的代码是用在前三个数组中搜索的方法来实现后三个数组的功能,因此只用了前3个数组
void swap(int d,int a,int b)
{
    int t=sw[d][a];
    sw[d][a]=sw[d][b];
    sw[d][b]=t;
}
int main()
{
    int i,j,k,cnt,t;
    char s[10];
    while (scanf("%s",s)!=EOF)
    {
        if (s[2]=='L')
        {
            scanf("%d%d%d",&x,&y,&z);
            printf("START\n");
            for (i=0;i<3;i++)
                for (j=0;j<1000;j++)
                    sw[i][j]=j;
        }
        if (s[0]=='S')
        {
            scanf("%d%d",&r,&t);
            int kk=s[4]-'1';
            swap(kk,r,t);
        }
        if (s[2]=='N')
        {
            scanf("%d",&cnt);
            if (cnt>x*y*z) continue;
            cnt-=1;
            k=cnt%z;
            cnt/=z;
            j=cnt%y;
            cnt/=y;
            i=cnt;
            for (t=0;t<x;t++)
                if (sw[0][t]==i)
                {
                    i=t; break;
                }
            for (t=0;t<y;t++)
                if (sw[1][t]==j)
                {
                    j=t; break;
                }
            for (t=0;t<z;t++)
                if (sw[2][t]==k)
                {
                    k=t; break;
                }
            printf("%d %d %d\n",i,j,k);
        }
        if (s[0]=='Q')
        {
            scanf("%d%d%d",&i,&j,&k);
            i=sw[0][i];
            j=sw[1][j];
            k=sw[2][k];
            cnt=(i*y+j)*z+k;
            printf("%d\n",cnt+1);
        }
    }
    return 0;
}       

by pxhdg