NOJ [1280] Go for a Psychological Test

来源:互联网 发布:百度派 知乎 编辑:程序博客网 时间:2024/06/08 03:59
链接地址:http://ac.nbutoj.com/Problem/view.xhtml?id=1280

此题只要理解了就很简单了。
矩阵快速幂。
因为T很大,如果一个一个乘的话,那么肯定会超时的。
将原始数据存在a数组里,结果存在b数组里。
所以我的方法就是将输入的T转换成二进制倒序存在一个数组te[]里。
然后对于二进制数位循环,每次都将矩阵a自乘,第一次除外。
然后判断te[i]是否为1,如果是第一个1,那么直接将a矩阵赋值给b,否则就将a矩阵与b矩阵相乘,结果保存在b矩阵中。

以下是我AC的代码。

#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

int m, n;
int a[30][30], b[30][30], c[30][30], d[30][30];

int main()
{
while (~scanf("%d%d\n", &n, &m))
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(0));
memset(c, 0, sizeof(c));
memset(d, 0, sizeof(d));
for (int i = 0; i < n; i++)
{
int b[4];
scanf("A.%X B.%X C.%X D.%X\n", &b[0], &b[1], &b[2], &b[3]);
for (int j = 0; j < 4; j++)
{
if (b[j] >= 10 && b[j] <= 14) b[j] = b[j] - 10 + n;
else
{
char str[8];
sprintf(str, "%X", b[j]);
sscanf(str, "%d", &b[j]);
b[j]--;
}
a[i][b[j]] = 1;
}
}
n += 5;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
d[i][j] = a[i][j];
}
}
while (m--)
{
int x;
scanf("%d", &x);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
a[i][j] = d[i][j];
}
}
int num = 0;
bool te[35];
while (x)
{
te[num++] = x % 2;
x /= 2;
}
int p = 1;
for (int y = 0; y < num; y++)
{
if (y)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
c[i][j] = 0;
for (int k = 0; k < n; k++)
{
c[i][j] += (a[i][k] * a[k][j]);
}
if(c[i][j]) c[i][j] = 1;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
a[i][j] = c[i][j];
}
}
}
if (te[y])
{
if (p)
{
p = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
b[i][j] = a[i][j];
}
}
}
else
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
c[i][j] = 0;
for (int k = 0; k < n; k++)
{
c[i][j] += (a[i][k] * b[k][j]);
}
if(c[i][j]) c[i][j] = 1;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
b[i][j] = c[i][j];
}
}
}
}
}
int s = 0;
for (int i = n - 5; i < n; i++)
{
s += b[0][i];
}
if (s == 0) printf("TT loves to lie\n");
else
{
int nn = 0;
for (int i = n - 5; i < n; i++)
{
if (b[0][i])
{
nn++;
if (nn == s) printf("%c\n", i + 'A' - n + 5);
else printf("%c ", i + 'A' - n + 5);
}
}
}
}
}

return 0;
}

0 0
原创粉丝点击