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

poj3735 Training little cats

2015-07-20 21:01 393 查看
题意为有n只猫 而你有m次操作 每次操作分k个步骤 每个步骤有3种选择

1:给第i个猫a个花生

2:让第i个猫把它所有的花生都吃掉

3:交换两个猫的花生

第一眼看过去以为是水题 后来发现m很大 大到o(n)都会t掉 所以就需要简化操作 用矩阵 可以将k个步骤整合成一个步骤

对于1 2 3只要构造 如下的矩阵 就可以达到相应的功能



整合成一个矩阵后 再利用矩阵快速幂来求就可以了

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include<stack>
#define inf 0x3f3f3f3f
#define ll long long
#define bug puts("bugbugbug");
using namespace std;
const int maxn = 105;
const int maxm = 105;
//ll mod=3000000007;

int a[100005];
struct Matrix {
    int n, m;
    ll a[maxn][maxm];
    void clear() {
        n = m = 0;
        memset(a, 0, sizeof(a));
    }
    Matrix operator * (const Matrix &b) const { //实现矩阵乘法
        Matrix tmp;
        tmp.n = n;
        tmp.m = b.m;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < b.m; j++) tmp.a[i][j] = 0;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++) {
                if (!a[i][j]) continue;
                for (int k = 0; k < b.m; k++)
                    tmp.a[i][k] += a[i][j] * b.a[j][k];//, tmp.a[i][k] %= mod;
            }

        return tmp;
    }
    void Copy(const Matrix &b) {
        n = b.n, m = b.m;
        for (int i = 0; i < n; i++)
            for(int j = 0; j < m; j++) a[i][j] = b.a[i][j];
    }
    void unit(int sz) {
        n = m = sz;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) a[i][j] = 0;
            a[i][i] = 1;
        }
    }
};
Matrix A, B,C;
Matrix Matrix_pow(Matrix A, ll k) { //矩阵快速幂
    Matrix res;
    res.clear();
    res.n = res.m = A.n;
    for (int i = 0; i < A.n; i++) res.a[i][i] = 1;
    while(k) {
        if (k & 1) res.Copy(A * res);
        k >>= 1;
        A.Copy(A * A);
    }
    return res;
}
int main()
{
     int n,m,k;
    while(~scanf("%d%d%d",&n,&m,&k)&&n+m+k)
    {
        A.clear();
        A.n=n+1;A.m=1;
        A.a
[0]=1;
        B.clear();
        B.n=B.m=n+1;
        for(int i=0;i<=n;i++)
            B.a[i][i]=1;
        for(int i=0;i<k;i++){
            char ff[20];
            scanf("%s",ff);
            if(ff[0]=='g'){
               int a;
               scanf("%d",&a);
               B.a[a-1]
++;
            }
            else if(ff[0]=='e'){
                int a;
                scanf("%d",&a);
                for(int j=0;j<=n;j++)
                B.a[a-1][j]=0;
            }
            else {
                int a,b;
                scanf("%d%d",&a,&b);
                for(int j=0;j<=n;j++)
                swap(B.a[a-1][j],B.a[b-1][j]);
            }
            }
       C.Copy(Matrix_pow(B,m)*A);
       for(int i=0;i<n;i++)
       {
           printf("%lld",C.a[i][0]);
       if(i==n-1)printf("\n");
       else printf(" ");
       }
    }
}


虽然m<int 但每次操作可能增加多个花生,所以注意要long long输出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: