2 条题解

  • 1
    @ 2024-5-13 17:05:52
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 110;
    
    ll T;
    int n, m, lim, len[N], act, now[10][10];
    char s[10][10], t[10][10];
    
    struct mat {
        ll a[65][65];
        mat() {memset(a, 0, sizeof(a));}
        mat operator * (mat &x) {
            mat ans;
            for(int i = 0; i <= lim; ++i) 
                for(int j = 0; j <= lim; ++j) 
                    for(int k = 0; k <= lim; ++k) 
                        ans.a[i][j] += a[i][k] * x.a[k][j];
            return ans;
        }
        mat Pow(ll t, mat a) {
            mat ans; ans.a[0][0] = 1;
            while(t) {
                if(t & 1) ans = ans * a;
                a = a * a; t >>= 1;
            }
            return ans;
        }
    }c[61], C;
    
    int idx(int x, int y) {return (x - 1) * m + y;}
    
    void print(mat x, bool flag) {
        puts("#####################");
        if(flag) {
            for(int i = 0; i <= lim; ++i) printf("%lld ", x.a[0][i]);
            puts("");
            return;
        }
        for(int i = 0; i <= lim; ++i) {
            printf("%d: ", i);
            for(int j = 0; j <= lim; ++j) {
                printf("%lld ", x.a[i][j]);
            }
            puts("");
        }
        puts("#####################");
    }
    
    int main() {
        scanf("%d%d%lld%d", &n, &m, &T, &act);
        lim = n * m;
        for(int i = 1; i <= n; ++i) {
            scanf("%s", t[i] + 1);
            for(int j = 1; j <= m; ++j) t[i][j] -= '0', ++t[i][j];
        }
        for(int i = 1; i <= act; ++i) {
            scanf("%s", s[i] + 1);
            len[i] = strlen(s[i] + 1);
        }
        for(int pos = 1; pos <= 60; ++pos) {
            c[pos].a[0][0] = 1;
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
    //              putchar(s[t[i][j]][now[i][j]]);
                    now[i][j] = (now[i][j] % len[t[i][j]]) + 1;
                    if(s[t[i][j]][now[i][j]] >= '0' && s[t[i][j]][now[i][j]] <= '9') {
                        c[pos].a[0][idx(i, j)] = s[t[i][j]][now[i][j]] - '0';
                        c[pos].a[idx(i, j)][idx(i, j)] = 1;
                    } else {
                        if(s[t[i][j]][now[i][j]] == 'D') c[pos].a[idx(i, j)][idx(i, j)] = 0;
                        if(i > 1 && s[t[i][j]][now[i][j]] == 'N') 
                            c[pos].a[idx(i, j)][idx(i - 1, j)] = 1;
                        if(i < n && s[t[i][j]][now[i][j]] == 'S') 
                            c[pos].a[idx(i, j)][idx(i + 1, j)] = 1;
                        if(j > 1 && s[t[i][j]][now[i][j]] == 'W') 
                            c[pos].a[idx(i, j)][idx(i, j - 1)] = 1;
                        if(j < m && s[t[i][j]][now[i][j]] == 'E') 
                            c[pos].a[idx(i, j)][idx(i, j + 1)] = 1;
                    }
                }
            }
    //        puts("");
        }
        C = c[1];
        for(int pos = 2; pos <= 60; ++pos) C = C * c[pos];
        C = C.Pow(T / 60, C);
        for(int pos = 1; pos <= T % 60; ++pos) {
    //        printf("Round # %d\n", pos);
            C = C * c[pos];
    //        print(c[pos], 0);
    //        printf("The test # %d\n", pos);
    //        print(C, 1);
        }
        ll ans = 0;
        for(int i = 1; i <= lim; ++i) ans = max(ans, C.a[0][i]);
        printf("%lld\n", ans);
        return 0;
    }
    
    
    • @ 2024-5-13 17:06:12

      这是另一个类似于传送带的结构。左边的设备0间隔地产生石头并向东传送。设备1向右传送,直到设备2。10秒后,总共产生了5个石头,2个在传送带上,3个在最右边。

    • @ 2024-5-13 17:12:53

      很有思维难度的一个题目。但是这题无论哪里都没有给出T的数据范围,这谁看的出来是矩阵快速幂啊... 将当前矩阵写成一个一维向量,并且钦定f[0]=1,那么i*(m-1)+j代表的就是原来位置(i,j)的石头数量。 因为操作序列长度小于等于6,而gcd(1,2,3,4,5,6)=60,也就是说每个操作序列在重复60次后都一定会回到位置1。那么可以把T分成两部分。 构造c[pos]表示第pos次操作的转移矩阵。(这里用(i,j)表示坐标(i,j)在一维向量中的位置)。

  • 1
    @ 2023-9-29 14:53:47

    #include <bits/stdc++.h> #include <unordered_map>

    using namespace std; #define ENDL "\n" #define lowbit(x) (x & (-x)) typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef pair<double, double> pdd; const double eps = 1e-8; const double pi = acos(-1.0); const int inf = 0x3f3f3f3f; const double dinf = 1e300; const ll INF = 1e18; const int Mod = 1e9 + 7; const int maxn = 2e5 + 10;

    int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }

    int lcm(int a, int b) { return a / gcd(a, b) * b; }

    struct Matrix { int n, m; ll a[65][65];

    Matrix() {}
    
    Matrix(int x, int y) {
        n = x, m = y;
        memset(a, 0, sizeof a);
    }
    
    Matrix operator*(const Matrix &p) const {
        Matrix ret(n, p.m);
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= p.m; j++)
                for (int k = 0; k <= m; k++)
                    ret.a[i][j] += a[i][k] * p.a[k][j];
        return ret;
    }
    
    void print() {
        cout << "-----------------" << endl;
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++)
                cout << a[i][j] << " ";
            cout << endl;
        }
    }
    

    } t[65];

    Matrix qkp(Matrix mx, int q) { Matrix ans(mx.n, mx.m); for (int i = 0; i <= ans.n; i++) ans.a[i][i] = 1; while (q) { if (q & 1) ans = ans * mx; mx = mx * mx; q >>= 1; } return ans; }

    string s[15]; int b[10][10]; int n, m, num, cnt, tot;

    inline int ID(int p, int q) { return n * (p - 1) + q; }

    int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); cin >> n >> m >> num >> cnt; for (int i = 1; i <= n; i++) { cin >> s[0]; for (int j = 1; j <= s[0].size(); j++) { b[i][j] = s[0][j - 1] - '0'; } } for (int i = 0; i < cnt; i++) cin >> s[i]; tot = 1; for (int i = 0; i < cnt; i++) tot = lcm(tot, (int) s[i].size()); for (int i = 0; i < cnt; i++) { int x = tot / (int) s[i].size(); string res = ""; for (int j = 1; j <= x; j++) res += s[i]; s[i] = res; } Matrix G(n * m, n * m); for (int i = 0; i <= n * m; i++) G.a[i][i] = 1; for (int k = 1; k <= tot; k++) { //求出每秒的转移矩阵 t[k].n = t[k].m = n * m, t[k].a[0][0] = 1; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { char ch = s[b[i][j]][k - 1]; if (ch >= '0' && ch <= '9') t[k].a[0][ID(i, j)] = ch - '0', t[k].a[ID(i, j)][ID(i, j)] = 1; else if (ch == 'N' && i > 1) t[k].a[ID(i, j)][ID(i - 1, j)] = 1; else if (ch == 'S' && i < n) t[k].a[ID(i, j)][ID(i + 1, j)] = 1; else if (ch == 'W' && j > 1) t[k].a[ID(i, j)][ID(i, j - 1)] = 1; else if (ch == 'E' && j < m) t[k].a[ID(i, j)][ID(i, j + 1)] = 1; } // t[k].print(); G = G * t[k]; } int x = num / tot, y = num % tot; Matrix F(0, n * m); F.a[0][0] = 1; G = qkp(G, x); F = F * G; for (int k = 1; k <= y; k++) F = F * t[k]; ll ans = 0; for (int i = 1; i <= n * m; i++) ans = max(ans, F.a[0][i]); cout << ans << ENDL; return 0; }

    • 1

    信息

    ID
    117
    时间
    1000ms
    内存
    128MiB
    难度
    6
    标签
    递交数
    24
    已通过
    11
    上传者