• LA 3510 (置换 循环分解) Pixel Shuffle


    思路挺简单的,题目中的每个命令(包括命令的逆)相当于一个置换。

    用O(n2k)的时间复杂度从右往左求出这些置换的乘积A,然后求m使Am = I(I为全等置换)

    还是先把A分解循环,m则等于所有循环节长度的最小公倍数。

    需要注意的是:

    执行命令是从右往左执行的,这是题目中说的=_=

    其他命令还好,mix那个命令把我搞得晕头转向,题中给的是反的,我们要反过来求原图像(i, j)在新图像中的位置。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <string>
      5 #include <sstream>
      6 #include <vector>
      7 using namespace std;
      8 
      9 int gcd(int a, int b)
     10 { return b == 0 ? a : gcd(b, a%b); }
     11 
     12 int lcm(int a, int b)
     13 { return a / gcd(a, b) * b; }
     14 
     15 const int maxn = 1025;
     16 int n;
     17 char s[300], op[35][10];
     18 
     19 inline int ID(int i, int j)
     20 { return i*n + j; }
     21 
     22 int newpos(int i, int j, const char* op)
     23 {
     24      if(op[0] == 'r') return ID(n-j-1, i);
     25      if(op[0] == 's') return ID(i, n-j-1);
     26      if(op[0] == 'b' && op[1] == 'h')
     27      {
     28          if(i >= n/2) return ID(i, n-j-1);
     29          return ID(i, j);
     30      }
     31      if(op[0] == 'b' && op[1] == 'v')
     32      {
     33          if(i >= n/2) return ID(n-(i-n/2)-1, j);
     34          return ID(i, j);
     35      }
     36      if(op[0] == 'd')
     37      {
     38          if(i & 1) return ID(n/2 + i/2 ,j);
     39          return ID(i/2, j);
     40      }
     41      if(op[0] == 'm')
     42      {
     43          int k = i/2;
     44          if(j < n/2) return i % 2 == 0 ? ID(k*2, j*2) : ID(k*2, j*2+1);
     45          else return i % 2 == 0 ? ID(2*k+1, 2*(j-n/2)) : ID(2*k+1, 2*(j-n/2)+1);
     46      }
     47      return ID(i, j);
     48 }
     49 
     50 int cur[maxn * maxn], origin[maxn * maxn];
     51 
     52 void apply(const char* op)
     53 {
     54     for(int i = 0; i < n*n; i++) origin[i] = cur[i];
     55     bool inv = op[strlen(op)-1] == '-' ? true : false;
     56     for(int i = 0; i < n; i++)
     57         for(int j = 0; j < n; j++)
     58         {
     59             int p = ID(i, j), p2 = newpos(i, j, op);
     60             if(inv) cur[p] = origin[p2];
     61             else cur[p2] = origin[p];
     62         }
     63 }
     64 
     65 bool vis[maxn * maxn];
     66 
     67 int solve()
     68 {
     69     memset(vis, false, sizeof(vis));
     70     int ans = 1;
     71     for(int i = 0; i < n*n; i++) if(!vis[i])
     72     {
     73         int cnt = 0, j = i;
     74         do
     75         {
     76             vis[j] = 1;
     77             cnt++;
     78             j = cur[j];
     79         }while(j != i);
     80         ans = lcm(cnt, ans);
     81     }
     82     return ans;
     83 }
     84 
     85 int main()
     86 {
     87     //freopen("in.txt", "r", stdin);
     88 
     89     int T;
     90     scanf("%d", &T);
     91     for(int kase = 0; kase < T; kase++)
     92     {
     93         if(kase) puts("");
     94 
     95         scanf("%d", &n); getchar();
     96         string line, temp;
     97         getline(cin, line);
     98         stringstream ss(line);
     99         vector<string> op;
    100         while(ss >> temp) op.push_back(temp);
    101 
    102         for(int i = 0; i < n*n; i++) cur[i] = i;
    103         for(int i = op.size() - 1; i >= 0; i--) apply(op[i].c_str());
    104         printf("%d
    ", solve());
    105     }
    106 
    107     return 0;
    108 }
    代码君
  • 相关阅读:
    React组件二
    React组件一
    React新接触
    清除浮动的方法
    div section article aside的理解
    html引入外部的jswenjian
    绘制扇形,空心文字,实心文字,颜色线性 放射性渐变
    绘制扇形空心 实心文字 ,颜色线性渐变,颜色放射性渐变
    绘制圆弧的几种简单方法
    求两个有序数组的中位数
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4333952.html
Copyright © 2020-2023  润新知