zoukankan      html  css  js  c++  java
  • BZOJ 2973 入门OJ4798 石头游戏

    矩阵递推

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #define ll long long
    #include <algorithm>
    using namespace std;
    int n, m, t, act;
    int opt[2000], len[100];
    char s[20][70];
    struct Matrix {
    	static const int N = 75;
    	ll num[N][N];
    	void clear() {
    		memset(num, 0, sizeof(num));
    	}
    	void unit(){
    		clear();
    		for(int i = 0; i < N; i++) num[i][i] = 1ll;
    	}
    	/*void print() {
    		for(int i = 0; i < 10; i++) {
    			for(int j = 0; j < 10; j++) {
    				printf("%d", num[i][j]);
    			}
    			cout<<endl;
    		}
    		cout<<endl;
    	} */
    };
    Matrix operator * (const Matrix & a, const Matrix & b) {
    	Matrix res;
    	res.clear();
    	for(int i = 0; i <= n * m; i++) {
    		for(int j = 0; j <= n * m; j++) {
    			for(int k = 0; k <= n * m; k++) {
    				res.num[i][j] += a.num[i][k] * b.num[k][j];
    			}
    		}
    	}
    	return res;
    }
    Matrix operator ^ (Matrix a, ll k) {
    	Matrix ans;
    	ans.unit();
    	while(k) {
    		if(k & 1ll) ans = ans * a;
    		a = a * a;
    		k >>= 1;
    	}
    	return ans;
    }
    Matrix build(int k) {
    	Matrix ans;
    	ans.clear();
    	ans.num[0][0] = 1ll;
    	for(int i = 1; i <= n * m; i++) {
    		int ind = opt[i], cur = k % len[ind];
    		switch (s[ind][cur]) {
    			case 'W' : if(i > 1) {ans.num[i][i - 1] = 1ll;}break;
    			case 'E' : if(i < m * n) {ans.num[i][i + 1] = 1ll;}break;
    			case 'N' : if(i > m) {ans.num[i][i - m] = 1ll;}break;
    			case 'S' : if(i < m * n - m) {ans.num[i][i + m] = 1ll;}break;
    			case 'D' : break;
    			default : ans.num[0][i] = s[ind][cur] - '0';ans.num[i][i] = 1ll;break;
    		}
    	}
    	return ans;
    }
    Matrix r1, r2, tmp;
    int main() {
    	cin >> n >> m >> t >> act;
    	for(int i = 1; i <= n * m; i++) scanf("%1d", &opt[i]),opt[i]++;
    	for(int i = 1; i <= act; i++) cin>>s[i],len[i] = strlen(s[i]);
    	tmp.unit();
    	for(int i = 0; i < 60; i++) {
    		if(i == (t % 60)) r2 = tmp;
    		tmp = tmp * build(i);
    	}
    	r1 = tmp;
    	r1 = r1 ^ (t/60); 
    	r1 = r1 * r2;
    	ll ma = 0ll;
    	for(int i = 1; i <= n * m; i++) ma = max(ma, r1.num[0][i]);
    	cout<<ma<<endl;
    	return 0;
    }
    
  • 相关阅读:
    [刷题] PTA 7-32 说反话-加强版
    [算法] 堆
    [笔记] 《c++ primer》显示器程序 Chapter7
    [笔记] 《c++ primer》书店程序 Chapter7
    [c++] <vector>
    [笔记] 《c++ primer》书店程序 Chapter2
    [笔记] 《c++ primer》书店程序 Chapter 1
    253. Meeting Rooms II
    461. Hamming Distance
    252. Meeting Rooms
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8560353.html
Copyright © 2011-2022 走看看