您的位置:首页 > 大数据 > 人工智能

poj 3735 Training little cats(构造矩阵)

2014-06-13 17:16 393 查看
http://poj.org/problem?id=3735

大致题意:

有n只猫,开始时每只猫有花生0颗,现有一组操作,由下面三个中的k个操作组成:

1. g i 给i只猫一颗花生米

2. e i 让第i只猫吃掉它拥有的所有花生米

3. s i j 将猫i与猫j的拥有的花生米交换

现将上述一组操作循环m次后,问每只猫有多少颗花生?

很明显,要先构造矩阵,构造一个(n+1)*(n+1)的矩阵a,初始化为单位矩阵。

g i : a[i][n+1] += 1;

e i : a[i][j] = 0;(1 <= j <= n+1)

s i j : swap(a[i][k],a[j][k])(1 <= k <= n+1)

然后矩阵快速幂就ok了。

注意m很大,k也不小,要用long long .

#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
#define C 240
#define S 20
using namespace std;
const int maxn = 110;
int n,m,k;

struct matrix
{
    LL mat[maxn][maxn];
    void init()
    {
        memset(mat,0,sizeof(mat));
        for(int i = 1; i <= n+1; i++)
            mat[i][i] = 1;
    }
}a,b;

matrix mul(matrix a, matrix b)
{
    matrix ans;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i = 1; i <= n+1; i++)
    {
        for(int k = 1; k <= n+1; k++)
        {
            if(a.mat[i][k] == 0) continue;
            for(int j = 1; j <= n+1; j++)
                ans.mat[i][j] += a.mat[i][k] * b.mat[k][j];
        }
    }
    return ans;
}

matrix pow(matrix a, int nn)
{
    matrix ans;
    ans.init();
    while(nn)
    {
        if(nn&1)
            ans = mul(ans,a);
        a = mul(a,a);
        nn >>= 1;
    }
    return ans;
}

int main()
{
    char ch[3];
    int x,y;
    while(~scanf("%d %d %d",&n,&m,&k))
    {
        if(n == 0 && m == 0 && k == 0) break;
        a.init();
        memset(b.mat,0,sizeof(b.mat));
        b.mat[n+1][1] = 1;
        while(k--)
        {
            scanf("%s",ch);
            if(ch[0] == 'g')
            {
                scanf("%d",&x);
                a.mat[x][n+1] += 1;
            }
            else if(ch[0] == 'e')
            {
                scanf("%d",&x);
                for(int i = 1; i <= n+1; i++)
                    a.mat[x][i] = 0;
            }
            else
            {
                scanf("%d %d",&x,&y);
                for(int i = 1; i <= n+1; i++)
                    swap(a.mat[x][i],a.mat[y][i]);
            }
        }
        a = pow(a,m);
		matrix ans = mul(a,b);
		for(int i = 1; i <= n; i++)
		{
			printf("%lld",ans.mat[i][1]);
			if(i == n) printf("\n");
			else printf(" ");
		}
    }
    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: