现在的位置: 首页 > 综合 > 正文

poj 3735 Training little cats(构造矩阵快速幂)

2014年09月29日 ⁄ 综合 ⁄ 共 2744字 ⁄ 字号 评论关闭
Training little cats
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 8313   Accepted: 2000

Description

Facer's pet cat just gave birth to a brood of little cats. Having considered the health of those lovely cats, Facer decides to make the cats to do some exercises. Facer has well designed a set of moves for his cats. He is now asking you to supervise the
cats to do his exercises. Facer's great exercise for cats contains three different moves:
g i : Let the ith cat take a peanut.
e i : Let the ith cat eat all peanuts it have.
s i j : Let the ith cat and jth cat exchange their peanuts.
All the cats perform a sequence of these moves and must repeat it m times! Poor cats! Only Facer can come up with such embarrassing idea. 
You have to determine the final number of peanuts each cat have, and directly give them the exact quantity in order to save them.

Input

The input file consists of multiple test cases, ending with three zeroes "0 0 0". For each test case, three integers nm and k are given firstly, where n is the number of cats and k is the length of the move
sequence. The following k lines describe the sequence.
(m≤1,000,000,000, n≤100, k≤100)

Output

For each test case, output n numbers in a single line, representing the numbers of peanuts the cats have.

Sample Input

3 1 6
g 1
g 2
g 2
s 1 2
g 3
e 2
0 0 0

Sample Output

2 0 1

Source

题意:有n只猫,k个操作为一个系列,一共做m次
题解:构造矩阵快速幂,先用乘法原理将操作矩阵合并,然后用快速幂,不过普通的会超时,注意到一行最多只有2个不为零的数,所以将乘法改成
for (int i=0;i<N;i++)for (int j=0;j<N;j++)for (int k=0;k<N;k++)
a[i][j]+=b[i][k]*c[k][j];
改写为
for (int i=0;i<N;i++)for (int j=0;j<N;j++)if (b[i][j])for (int k=0;k<N;k++)
a[i][k]+=b[i][j]*c[j][k];

就可以AC了~~~~~

#include<stdio.h>
#include<string.h>
long long n,m,k,c[103],cc[103];
char s[10];
struct point{
    long long a[103][103];
}e,res;
struct point mult(struct point x,struct point y)
{
    struct point temp;
    int i,j,k;

    memset(temp.a,0,sizeof(temp.a));
    for(i=1;i<=n+1;i++)
    {
        for(j=1;j<=n+1;j++)
        {
            if(x.a[i][j])
            for(k=1;k<=n+1;k++)
                temp.a[i][k]+=x.a[i][j]*y.a[j][k];
        }
    }

    return temp;
};
void gg(int x)
{
    int i;
    memset(res.a,0,sizeof(res.a));
    for(i=1;i<=n+1;i++) res.a[i][i]=1;
    res.a[n+1][x]=1;
    e=mult(e,res);
}
void ee(int x)
{
    int i;
    memset(res.a,0,sizeof(res.a));
    for(i=1;i<=n+1;i++) res.a[i][i]=1;
    res.a[x][x]=0;
    e=mult(e,res);
}
void ss(int x,int y)
{
    int i;
    memset(res.a,0,sizeof(res.a));
    for(i=1;i<=n+1;i++) res.a[i][i]=1;
    res.a[x][x]=res.a[y][y]=0;
    res.a[y][x]=res.a[x][y]=1;
    e=mult(e,res);
}
void init()
{
    int x,y,i;

    memset(c,0,sizeof(c));
    memset(e.a,0,sizeof(e.a));
    for(i=1;i<=n+1;i++) e.a[i][i]=1;
    c[n+1]=1;
    for(i=0;i<k;i++)
    {
        scanf("%s%d",s,&x);
        if(s[0]=='g') gg(x);
        else if(s[0]=='e') ee(x);
        else
        {
            scanf("%d",&y);
            ss(x,y);
        }
    }
}
void solve()
{
    int i;

    memset(res.a,0,sizeof(res.a));
    for(i=1;i<=n+1;i++) res.a[i][i]=1;
    while(m)
    {
        if(m&1) res=mult(res,e);
        e=mult(e,e);
        m>>=1;
    }
}
void output()
{
    int i,j;

    for(i=1;i<=n;i++)
    {
        for(cc[i]=0,j=1;j<=n+1;j++)
        {
            cc[i]+=c[j]*res.a[j][i];
        }
    }
    for(i=1;i<n;i++) printf("%lld ",cc[i]);
    printf("%lld\n",cc[i]);
}
int main()
{
    while(scanf("%lld%lld%lld",&n,&m,&k),n||m||k)
    {
        init();
        solve();
        output();
    }

    return 0;
}

抱歉!评论已关闭.