【ZOJ 2974】Just Pour the Water(矩阵快速幂)

传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2974

题意 给出n个杯子与初始水量同时进行操作 将其中的水同时平均分入所指定的杯子 进行x次后 输出杯子剩余水量

刚拿到这个题,第一反应是递推找规律,但是因为每个杯子的初始水量是未知的,所以能找的只是每个杯子水量与其余杯子水量的关系。

但是看到了操作次数巨大,而且最多只有20个杯子,感觉可以用快速幂去做。

我们假设矩阵a[i][j]代表第i个杯子的水有a[i][j]来自第j个杯子,这样用init矩阵表示初始水量,unit矩阵表示每次操作后的变化,最后init*pow(unit,k)即为所求。

注意当某一个杯子不用向其他杯子操作时,要将相应位置填为1,因为这个原因wa了8次。

总结:这是道思维大于算法的题,算法只是简单的矩阵快速幂,但是思维与经验很重要,比如对于数据的理解。由于操作数巨大,所以可以考虑一发快速幂。

代码如下:

///BY: Torrance_ZHANG
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
struct JZ {
    double a[25][25];
} init, unit;
int n;
JZ multi(JZ x, JZ y) {
    JZ z;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            z.a[i][j] = 0.0;
            for (int k = 0; k < n; k++) {
                z.a[i][j] += (x.a[i][k] * y.a[k][j]);
            }
        }
    }
    return z;
}
JZ Pow(JZ x, JZ y, int k) {
    while (k) {
        if (k % 2 != 0)
            y = multi(y, x);
        x = multi(x, x);
        k /= 2;
    }
    return y;
}
void init_JZ(int n) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            init.a[i][j] = 0.0;
            unit.a[i][j] = 0.0;
        }
    }
}
double aa[25];
int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        init_JZ(n);
        for (int i = 0; i < n; i++)
            scanf("%lf", &init.a[0][i]);
        int tmp = 0, xh;
        for (int i = 0; i < n; i++) {
            scanf("%d", &tmp);
            if (tmp == 0)                ///最容易被忽略的一点,若输入为0,则全部的水都来自本身
                unit.a[i][i] = 1;
            else {
                for (int j = 0; j < tmp; j++) {
                    scanf("%d", &xh);
                    unit.a[i][xh - 1] += 1.0 / tmp;
                }
            }
        }
        int time;
        scanf("%d", &time);
        JZ res = Pow(unit, init, time);
        for (int i = 0; i < n; i++) {
            printf("%.2f", res.a[0][i]);
            printf(i == n - 1 ? "\n" : " ");
        }
    }
}
时间: 2024-10-29 19:11:53

【ZOJ 2974】Just Pour the Water(矩阵快速幂)的相关文章

zoj 2974 Just Pour the Water矩阵快速幂

Just Pour the Water Time Limit: 2 Seconds      Memory Limit: 65536 KB Shirly is a very clever girl. Now she has two containers (A and B), each with some water. Every minute, she pours half of the water in A into B, and simultaneous pours half of the

ZOJ 2974 Just Pour the Water

矩阵快速幂. 构造一个矩阵,$a[i][j]$表示一次操作后,$j$会从$i$那里得到水的比例.注意$k=0$的时候,要将$a[i][j]$置为$1$. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vecto

ACM-ICPC 2018 焦作赛区网络预赛 L:Poor God Water(矩阵快速幂)

God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him that some sequence of eating will make them poisonous. Every hour, God Water will eat one kind of food among meat, fish and chocolate. If there are 3 c

zoj 3538 Arrange the Schedule(矩阵快速幂)

Arrange the Schedule Time Limit: 1 Second      Memory Limit: 65536 KB In Summer 2011, the ZJU-ICPC Team has a n-days training schedule. ZJU-ICPC Team has been divided into 4 Group: Akiba, BiliBili, CIA, Double(Group A, B, C, D). There is a group in c

ZOJ 3256 Tour in the Castle 矩阵快速幂加速

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3256 题意:给一个n*m的棋盘,求从左上到左下的经过所有格子的方案数 在左边加一列问题就变成了求回路 由于m很大,所以我们需要按列dp 构造出矩阵后,用矩阵快速幂加速 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include&l

ZOJ 2794 Just Pour the Water 【矩阵快速幂】

给你n个杯子,每次有特定的到水规则,倒m次请问最后每个被子里还有多少水 我们很容易发现每次变化的规则相同,那么可以set 一个矩阵存放 然后多次倒水就相当于矩阵相乘,在m 范围达到(1<= M <= 1,000,000,000) 的情况下使用矩阵快速幂再好不过 这到题目注意的一点是,得使用Double 变量,如果使用FLoat会导致Wrong Answer Source Code: //#pragma comment(linker, "/STACK:16777216") /

dutacm.club Water Problem(矩阵快速幂)

Water Problem Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:1228   Accepted:121 [Submit][Status][Discuss] Description 函数 f:Z+→Z .已知 f(1),f(2) 的值,且对于任意 x>1,有 f(x+1)=f(x)+f(x?1)+sin(πx2) . 求 f(n) 的

zoj 2853 Evolution(矩阵快速幂)

Evolution is a long, long process with extreme complexity and involves many species. Dr. C. P. Lottery is currently investigating a simplified model of evolution: consider that we haveN (2 <= N <= 200) species in the whole process of evolution, inde

ZOJ 3690 &amp; HDU 3658 (矩阵快速幂+公式递推)

ZOJ 3690 题意: 有n个人和m个数和一个k,现在每个人可以选择一个数,如果相邻的两个人选择相同的数,那么这个数要大于k 求选择方案数. 思路: 打表推了很久的公式都没推出来什么可行解,好不容易有了想法结果WA到天荒地老也无法AC.. 于是学习了下正规的做法,恍然大悟. 这道题应该用递推 + 矩阵快速幂. 我们设F(n) = 有n个人,第n个人选择的数大于k的方案数: G(n) = 有n个人,第n个人选择的数小于等于k的方案数: 那么递推关系式即是: F(1)=m?k,G(1)=k F(n