HDU2371 矩阵计算转置
来源:互联网 发布:女士内裤 知乎 编辑:程序博客网 时间:2024/05/19 19:33
转http://blog.csdn.net/xingyeyongheng/article/details/9855103
Decode the Strings
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 766 Accepted Submission(s): 232
Problem Description
Bruce Force has had an interesting idea how to encode strings. The following is the description of how the encoding is done:
Let x1,x2,...,xn be the sequence of characters of the string to be encoded.
1. Choose an integer m and n pairwise distinct numbers p1,p2,...,pn from the set {1, 2, ..., n} (a permutation of the numbers 1 to n).
2. Repeat the following step m times.
3. For 1 ≤ i ≤ n set yi to xpi, and then for 1 ≤ i ≤ n replace xi by yi.
For example, when we want to encode the string "hello", and we choose the value m = 3 and the permutation 2, 3, 1, 5, 4, the data would be encoded in 3 steps: "hello" -> "elhol" -> "lhelo" -> "helol".
Bruce gives you the encoded strings, and the numbers m and p1, ..., pn used to encode these strings. He claims that because he used huge numbers m for encoding, you will need a lot of time to decode the strings. Can you disprove this claim by quickly decoding the strings?
Let x1,x2,...,xn be the sequence of characters of the string to be encoded.
1. Choose an integer m and n pairwise distinct numbers p1,p2,...,pn from the set {1, 2, ..., n} (a permutation of the numbers 1 to n).
2. Repeat the following step m times.
3. For 1 ≤ i ≤ n set yi to xpi, and then for 1 ≤ i ≤ n replace xi by yi.
For example, when we want to encode the string "hello", and we choose the value m = 3 and the permutation 2, 3, 1, 5, 4, the data would be encoded in 3 steps: "hello" -> "elhol" -> "lhelo" -> "helol".
Bruce gives you the encoded strings, and the numbers m and p1, ..., pn used to encode these strings. He claims that because he used huge numbers m for encoding, you will need a lot of time to decode the strings. Can you disprove this claim by quickly decoding the strings?
Input
The input contains several test cases. Each test case starts with a line containing two numbers n and m (1 ≤ n ≤ 80, 1 ≤ m ≤ 109). The following line consists of n pairwise different numbers p1,...,pn (1 ≤ pi ≤ n). The third line of each test case consists of exactly n characters, and represent the encoded string. The last test case is followed by a line containing two zeros.
Output
For each test case, print one line with the decoded string.
Sample Input
5 32 3 1 5 4helol16 80428938413 10 2 7 8 1 16 12 15 6 5 14 3 4 11 9scssoet tcaede n8 125 3 4 2 1 8 6 7encoded?0 0
Sample Output
hellosecond test caseencoded?
题目意思是给出n个字符的置换方式,经过m次转换后得到了最终字符串(就是给定的字符串),求最初的字符串分析:假定最初字符串序号是1,2,3,4,置换方式是3,1,2,4,即1,2,3,4置换一次后得到3,1,2,4构成的字符串将1 2 3 4置换为3 1 2 4,相当于下面的矩阵乘法:
如果置换m次则将置换矩阵*m次即可,最后乘上给定的字符串矩阵得到最终字符串矩阵(就是得到的矩阵第i行第j列是1表示由s[j]得到第s[i]个字符)但是本题是给定结果,叫我们求最初的矩阵,其实就是将原来矩阵求逆矩阵的m次A*B^m=C =>A=C*B^(-m),A*A^-1=I;//I是单位矩阵注意到这里的矩阵A元素为0或1且每一行每一列只有一个1,则A中的A[i][k]*B[k][j]=I[i][j]=1,i == j,所以A的逆矩阵就是A逆s[i][j]=A的s[j][i]
#define DeBUG#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <string>#include <set>#include <sstream>#include <map>#include <list>#include <bitset>using namespace std ;#define zero {0}#define INF 0x3f3f3f3f#define EPS 1e-6#define TRUE true#define FALSE falsetypedef long long LL;const double PI = acos(-1.0);//#pragma comment(linker, "/STACK:102400000,102400000")inline int sgn(double x){ return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);}#define N 100const int MAXN = 100;long long mod;struct Matrix{ int mat[MAXN][MAXN]; void Zero() { memset(mat, 0, sizeof(mat)); } void Unit() { memset(mat, 0, sizeof(mat)); for (int i = 0; i < MAXN; i++) mat[i][i] = 1; } void output() { int from = 1, to = 10; for (int i = from - 1; i < to; i++) { printf("%d ", i); } printf("\n"); for (int i = from; i < to; i++) { printf("%d=", i); for (int j = from; j < to; j++) { printf("%d ", mat[i][j]); } printf("\n"); } }};Matrix operator*(Matrix &a, Matrix &b){ Matrix tmp; tmp.Zero(); for (int k = 0; k < MAXN; k++) { for (int i = 0; i < MAXN; i++) { if (!a.mat[i][k]) continue; for (int j = 0; j < MAXN; j++) { tmp.mat[i][j] += a.mat[i][k] * b.mat[k][j] % mod; if ( tmp.mat[i][j] >= mod) tmp.mat[i][j] -= mod; } } } return tmp;}Matrix operator ^(Matrix a, int k){ Matrix tmp; tmp.Unit(); for (; k; k >>= 1) { if (k & 1) tmp = tmp * a; a = a * a; } return tmp;}int a[N];char s[1000];Matrix mt;int main(){#ifdef DeBUGs freopen("C:\\Users\\Sky\\Desktop\\1.in", "r", stdin);#endif int n, m; mod = 2; while (scanf("%d%d", &n, &m), n || m) { for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); } getchar(); gets(s + 1); mt.Zero(); for (int i = 1; i <= n; i++) { mt.mat[a[i]][i] = 1; } mt = mt ^ m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (mt.mat[i][j]) { printf("%c", s[j]); break; } } } printf("\n"); // mt.output(); } return 0;}
0 0
- HDU2371 矩阵计算转置
- hdu2371之矩阵快速幂
- hdu2371 矩阵乘法(求序列位置改变m次后的序列)
- 九度OJ 1193:矩阵转置 (矩阵计算)
- c# 矩阵计算(转)
- c# 矩阵计算(转)
- 一个函数关于计算n阶矩阵的转置
- 矩阵计算
- 矩阵计算
- 矩阵计算
- 矩阵计算
- n x n矩阵的转置矩阵,并计算对角线元素之和
- 转:用 Hadoop 计算共生矩阵
- 字符计算 矩阵转置 1-1/2+1/3-1/4+......+1/99-1/100
- 矩阵计算(C++)
- 矩阵特征值特征向量计算
- 矩阵的相关计算
- 用Haskell计算矩阵
- maven web项目部署到tomcat7
- Codeforces Round #265(div2)题解
- C# Windows Azure Queue的操作
- makefile
- Add Binary
- HDU2371 矩阵计算转置
- 16 ---TPC的简单编程
- Leetcode 细节实现 Longest Common Prefix
- NYOJ 62 笨小熊
- 单片机的输入输出接口操作
- HTPC改装19寸2U轻量级机架PC
- 1>e:\驱动编程\项目\myreloadkerneldriver\driver.c(117) : error C2220: warning tre ated as error - no 'objec
- 【LeetCode】N-Queens
- POJ3259