CF1458C Latin Square

对于一个排列 pi ,将其表示为 (i,pi) , 那么它的逆排列可表示为 (pi,i)

这道题 i,j,ai,j 均为排列,考虑用三元组 (i,j,ai,j) 表示。(为了方便下标从 0 开始)

那么操作可表示为:

  • R (i,j,k)(i,(j+1)modn,k)
  • L (i,j,k)(i,(j1)modn,k)
  • D (i,j,k)((i+1)modn,j,k)
  • U (i,j,k)((i1)modn,j,k)
  • I (i,j,k)(i,k,j)
  • C (i,j,k)(k,j,i)

只需要记录每一维的偏移量与最终的位置即可。

时间复杂度 O(n2+m)

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1000 , MAXM = 1e5;
int T , n , m , a[ MAXN + 5 ][ MAXN + 5 ][ 3 ] , b[ MAXN + 5 ][ MAXN + 5 ];
char op[ MAXM + 5 ];

int tag[ 3 ] , p[ 3 ];
int main( ) {
    scanf("%d",&T);
    while( T -- ) {
        scanf("%d %d",&n,&m);
        for( int i = 0 ; i < n ; i ++ )
            for( int j = 0 ; j < n ; j ++ ) {
                a[ i ][ j ][ 0 ] = i, a[ i ][ j ][ 1 ] = j;
                scanf("%d",&a[ i ][ j ][ 2 ]); a[ i ][ j ][ 2 ] --;
            }

        scanf("%s", op + 1 );
        for( int i = 0 ; i < 3 ; i ++ ) p[ i ] = i , tag[ i ] = 0;
        for( int i = 1 ; i <= m ; i ++ ) {
            if( op[ i ] == 'R' ) tag[ p[ 1 ] ] ++;
            if( op[ i ] == 'L' ) tag[ p[ 1 ] ] --;
            if( op[ i ] == 'D' ) tag[ p[ 0 ] ] ++;
            if( op[ i ] == 'U' ) tag[ p[ 0 ] ] --;
            if( op[ i ] == 'I' ) swap( p[ 1 ] , p[ 2 ] );
            if( op[ i ] == 'C' ) swap( p[ 0 ] , p[ 2 ] );
        } 
        for( int i = 0 ; i < 3 ; i ++ ) tag[ i ] = ( tag[ i ] % n + n ) % n;
        for( int i = 0 ; i < n ; i ++ )
            for( int j = 0 ; j < n ; j ++ )
                b[ ( a[ i ][ j ][ p[ 0 ] ] + tag[ 0 ] ) % n ][ ( a[ i ][ j ][ p[ 1 ] ] + tag[ 1 ] ) % n ] = ( a[ i ][ j ][ p[ 2 ] ] + tag[ 2 ] ) % n;
        for( int i = 0 ; i < n ; i ++ )
            for( int j = 0 ; j < n ; j ++ )
                printf("%d%c", b[ i ][ j ] + 1 , j == n - 1 ? '\n' : ' ' );
    }
    return 0;
}
posted @   chihik  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示