zoukankan      html  css  js  c++  java
  • TZOJ--5480: 孤衾易暖 // POJ--3735 Training little cats (矩阵快速幂)

    5480: 孤衾易暖 

    时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte

    描述

    哇,好难,我要放弃了(扶我起来,我还能A

    寒夜纵长,孤衾易暖,钟鼓渐清圆。

    生活也许有些不如意的地方,但是没有什么是拥有一只猫不能解决的,我最喜欢苏格兰折耳猫。

    现在我有n只小猫,我要训练这些猫去满足我奇奇怪怪的需求。

    就是要让他们去得到鱼,这样他们才会快乐。刚开始他们是没有鱼的

    我对这些猫有3种训练要求:

    第一种要求为get x,意为让第x只猫咪得到一条;

    第二种要求为eat x,意为让第x只猫咪吃掉它所有的鱼;

    第三种要求为exchange x y,意为让第x只猫咪和第y只猫咪交换他们的鱼。

    人们经常都是复读机,猫也不例外,你给他们设定某组操作,让他们重复就好了。

    他们需要重复执行某组操作(含有k个要求)m次,求最后它们都有多少只鱼。

    输入

     

    输入包括多组样例,读到文件结尾。

    输入的第一行为三个整数n,m,k,代表有n只猫,要重复的次数m和k个要求组成的操作。

    接下来有k行,每一行都有一个训练方式(m≤1,000,000,000, n≤100, k≤100)。

    输出

    对于每个样例都在一行上输出n个数,代表每只猫有多少只鱼。

    样例输入

    3 1 6
    get 1
    get 2
    get 2
    exchange 1 2
    get 3
    eat 2

    样例输出

     2 0 1

    提示

    第一只猫得到1条鱼,第2只猫得到1条鱼,第2只猫得到1条鱼,交换1和2的鱼数。

    第1只猫现在有2条鱼,第2只猫现在有1条鱼。第三只猫有一条鱼,然后第二只猫的鱼被吃完。

    所以第1只猫现在有2条鱼,第2只猫现在有0条鱼,第三只猫有1条鱼。而且只有一次,故输出2 0 1。

    题目来源

    TOJ

     

    题目链接:http://tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=5480

    http://poj.org/problem?id=3735

    两个题目是一样的,只不过一个英文题面一个中文题目

    按照题目要求构造出矩阵,重复的次数用矩阵快速幂计算

    对于题目要求的三种操作,可以按照下面的方法构造矩阵

    第一种要求为get x,意为让第x只猫咪得到一条;

    即x的位置+1

    第二种要求为eat x,意为让第x只猫咪吃掉它所有的鱼;

    即x的位置归0

    第三种要求为exchange x y,意为让第x只猫咪和第y只猫咪交换他们的鱼。

    即swap(x,y)

    #include <bits/stdc++.h>
    using namespace std;
    #define LL __int64
    struct A{
    	LL data[111][111];
    	int n;
    	void ini(int nn){//初始化全0矩阵 
    		n=nn;
    		memset(data,0,sizeof(data));
    	}
    	void dw(int nn){//单位矩阵 
    		ini(nn);
    		for(int i=0;i<=n;i++)data[i][i]=1;
    	}
    	A(){
    		n=2;
    		memset(data,0,sizeof(data));
    	}
    };
    int n;
    A operator* (A a,A b)//矩阵乘法,重载乘号 
    {
    	A ans;
    	for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=n;j++)
            {
                if(a.data[i][j]==0)continue;
                for(int k=0;k<=n;k++)
                {
                    ans.data[i][k]+=a.data[i][j]*b.data[j][k];
    
                }
            }
        }
    	return ans;
    }
    A operator^ (A a,int k)//矩阵次幂 
    {
    	A ans;
    	ans.dw(n);
    	while(k)
    	{
    		if(k&1)ans=ans*a;
    		a=a*a;
    		k>>=1;
    	}
    	return ans;
    }
    int main(){
    	int m,k,x,y;
    	A T;
    	char ch[15];
    	while(~scanf("%d%d%d",&n,&m,&k)){
    		T.dw(n);
    		while(k--){
    			scanf("%s",ch);
    			if(ch[0]=='g'){
    				scanf("%d",&x);
    				T.data[0][x]++;
    			}
    			else if(ch[0]=='e'){
    				if(ch[1]=='x'){
    					scanf("%d %d",&x,&y);
    					for(int i=0;i<=n;i++){
    						swap(T.data[i][x],T.data[i][y]);
    					}
    				}else {	
    					scanf("%d",&x);
    					for(int i=0;i<=n;i++){
    						T.data[i][x]=0;
    					}
    				}
    			}
    		}
    		T=T^m;
    		printf("%I64d",T.data[0][1]);
    		for(int i=2;i<=n;i++){
    			printf(" %I64d",T.data[0][i]);
    		}
    		puts("");
    	}
    }
    

      

  • 相关阅读:
    接口与实现分离
    C++的explicit关键字
    C++的类型转换
    使用catch做单元测试简介
    C++可调用对象与函数表
    在sublime中使用cppcheck
    你需要的代码静态检查
    构造析构与拷贝赋值那些事
    c++的关联容器入门(map and set)
    【致敬程序猿】
  • 原文地址:https://www.cnblogs.com/Anidlebrain/p/10060964.html
Copyright © 2011-2022 走看看