其他分享
首页 > 其他分享> > 2021.8.28 CCPC2021网络赛

2021.8.28 CCPC2021网络赛

作者:互联网

3题校内垫底的屑

1002:

循环节找到以后直接双指针就行
考场上没有细算循环节长度,按照1e5算的,交上去自然是wa。正解的循环节最大长度在\(2^3\times3^2\times5\times7\times11=27720\times n\),然后还可能有横跨两个循环节的部分,因此长度还要再乘个二。

// Problem: Time-division Multiplexing
// Contest: HDOJ
// URL: https://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=1031
// Memory Limit: 262 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
const int maxn = 107, maxm = 27720 * 100 * 2;
#define ll long long
int n, m, k, tot, T;
char s[maxm+7];
int rd() {
    int x;
    scanf("%d", &x);
    return x;
}
char a[107][14];
int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}
int lcm = 1, len[107], cnt[300], flag, ans, flag0;
int main() {
    T = rd();
    while (T--) {
        lcm = 1; ans = 999999999; tot = 0;
        memset(cnt, 0, sizeof(cnt));
        flag = 0;
        n = rd();
        for (int i = 1; i <= n; i++) {
            scanf("%s", a[i]);
            k = strlen(a[i]);
            for (int j = 0; j < k; j++) {
                if (cnt[a[i][j]]==0) {
                    flag++;
                }
                cnt[a[i][j]]++;
            }
            len[i] = k;
            lcm = k * lcm / gcd(k, lcm);    
        }
        lcm = lcm*2*n;
        for (int cur = 0; tot < lcm; cur++) {
            for (int i = 1; i <= n; i++) {
                s[tot++] = a[i][cur%len[i]];
            }
        }
        int l = 0, r = -1;
        flag0 = flag;
        flag = 0;
        memset(cnt, 0, sizeof(cnt));
        while (r < lcm) {
            while (flag < flag0 && r < lcm) {
                r++;
                if (r == lcm) break;
                if (cnt[s[r]] == 0) {
                    flag++;
                }
                cnt[s[r]]++;
            }
            if (r == lcm) break;
            while (flag == flag0 && l < r) {
                cnt[s[l]]--;
                if (cnt[s[l]] == 0) {
                    flag--;
                } 
                l++;
                if (flag == flag0)
                    ans = min(ans, r-l+1);
            }
            if (flag == flag0 && l <= r) 
            	ans = min(ans, r-l+1);    
        }
        
        //printf("s == %s\n", s);
        printf("%d\n", ans);
    }
    return 0;
}

1012:

wa傻了,待补。

标签:CCPC2021,cnt,return,int,2021.8,28,rd,循环,107
来源: https://www.cnblogs.com/YjmStr/p/15201643.html