[JZOJ5281]钦点题解--瞎搞+链表

[JZOJ5281]钦点题解--瞎搞+链表

题目链接

于 暴 力 过

img

分析

第一眼: 模拟美滋滋?!

然后数据范围...不太对

naiive模拟30pts

然后你交换字符串指针60pts

然后发现可以用链表记录指针的上下左右又是哪个指针,操作时只用操作边界就好了

敲代码的时候一定要仔细,一开始一个SB错误查了好久

另外想讲讲这个毒瘤字符串读入,它单个字符串亲测最长有1e5,那么你肯定不能用二维char数组来存.

于是乖乖用string,又跑了个倒数

看他们的代码是怎么跑得和香港记者一样快的,结果发现我还是naive了

直接搞一个总字符串长度的char数组全部读入

我们都已经是存指针了,干脆就存它在这个大数组中的开头位置就行了

又学会了一个船新操作

printf("%s",&str[ch[now]]);

代码

char str[11000005];
int f[1007][1007],p[1005][1005],ch[1000005],n,m,q,tot=0,pos=0;
int t[1500005][4];
inline void getin(){
    char c;int st=pos,l=0;
    while((c=getchar())<'a'||c>'z');
    str[pos++]=c,l++;
    while((c=getchar())>='a'&&c<='z')str[pos++]=c,l++;
    str[pos++]='\0';
    ch[tot]=st;
}
int main(){
    //freopen("appoint4.in","r",stdin);
    //freopen("wtf2.out","w",stdout);
    int x,y,xx,yy,l,r;
    read(n),read(m),read(q);
    for(ri i=1;i<=n;i++){
        for(ri j=1;j<=m;j++){
            f[i][j]=++tot,getin();
        }
    }
    for(ri i=1;i<=m;i++)f[0][i]=++tot,f[n+1][i]=++tot;
    for(ri i=1;i<=n;i++)f[i][0]=++tot,f[i][m+1]=++tot;//边界也要有指针
    for(ri i=0;i<=n+1;i++){
        for(ri j=0;j<=m+1;j++){//处理指针
            if(j)t[f[i][j]][0]=f[i][j-1];
            t[f[i][j]][1]=f[i][j+1];
            if(i)t[f[i][j]][2]=f[i-1][j];
            t[f[i][j]][3]=f[i+1][j];
        }
    }
    int a,b,c,d,p1,p2,p3,p4,ex,exx;
    while(q--){
        read(x),read(y),read(xx),read(yy),read(l),read(r);
        ex=x+l-1,exx=xx+l-1;
        p1=t[f[x][0]][1],p2=t[f[xx][0]][1],p3=t[f[ex][0]][1],p4=t[f[exx][0]][1];
        for(ri i=1;i<=m;i++){
            p[x][i]=p1,p[xx][i]=p2,p[ex][i]=p3,p[exx][i]=p4;
            p1=t[p1][1],p2=t[p2][1],p3=t[p3][1],p4=t[p4][1];
        }
        ex=y+r-1,exx=yy+r-1;
        p1=t[f[0][y]][3],p2=t[f[0][yy]][3],p3=t[f[0][ex]][3],p4=t[f[0][exx]][3];
        for(ri i=1;i<=n;i++){
            p[i][y]=p1,p[i][yy]=p2,p[i][ex]=p3,p[i][exx]=p4;
            p1=t[p1][3],p2=t[p2][3],p3=t[p3][3],p4=t[p4][3];
        }
        for(ri i=0;i<r;i++){
            a=y+i,c=yy+i;
            //printf("%d %d\n",a,c);
            t[t[p[x][a]][2]][3]=p[xx][c];
            t[t[p[xx][c]][2]][3]=p[x][a];
            swap(t[p[xx][c]][2],t[p[x][a]][2]);
            a=x+l-1,b=y+i,c=xx+l-1,d=yy+i;
            //printf("--%d %d %d %d--\n",a,b,c,d);
            t[t[p[a][b]][3]][2]=p[c][d];
            t[t[p[c][d]][3]][2]=p[a][b];
            swap(t[p[c][d]][3],t[p[a][b]][3]);
        }
        for(ri i=0;i<l;i++){
            a=x+i,c=xx+i;
            t[t[p[a][y]][0]][1]=p[c][yy];
            t[t[p[c][yy]][0]][1]=p[a][y];
            swap(t[p[a][y]][0],t[p[c][yy]][0]);
            a=x+i,b=y+r-1,c=xx+i,d=yy+r-1;
            t[t[p[a][b]][1]][0]=p[c][d];
            t[t[p[c][d]][1]][0]=p[a][b];
            swap(t[p[a][b]][1],t[p[c][d]][1]);
        }
    }
    int now;
    for(ri i=1;i<=n;i++){
        now=t[f[i][0]][1];
        for(ri j=1;j<=m;j++){
            //cout<<str[now];//printf("%s ",str[now]);
            printf("%s",&str[ch[now]]);//直接输出,很方便
            now=t[now][1];
            putchar(' ');
        }
        puts("");
    }
    return 0;
}

转载于:https://www.cnblogs.com/Rye-Catcher/p/9884147.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值