Summer school more than 2019 cattle off the fifth solution to a problem

A.digits 2

Portal

Meaning of the questions: to give you a n, a required output for each digit sum divisible by n and are themselves also divisible number n. n is not more than 100, the required number of digits is not more than 10,000.

Solution: directly to the output n n times.

Code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main() {
    int T,n;
    for (scanf("%d",&T);T--;) {
        scanf("%d",&n);
        for (int i = 0; i < n; i++) 
            printf("%d",n);
        printf("\n");
    }
    return 0;
}
View Code

 

 

B.generator 1

Portal

The meaning of problems: Known X0, X1, A, B, n-, MOD, X I = A * X I. 1- + B * X I-2 , seeking X n- % MOD

Solution: matrix fast power, with two units of the multiplier changed to ten units

Code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
#define maxn 2
const int N = 1e6 + 10;
struct Matrix {
    ll ma[maxn][maxn];
    Matrix() {
        memset(ma,0, sizeof(ma));
    }
}A,E;
char s[N];
ll mod;
Matrix mul(Matrix A,Matrix B) {
    Matrix C;
    for(int i=0;i<maxn;i++)
        for(int j=0;j<maxn;j++)
            for(int k=0;k<maxn;k++)
                C.ma[i][j]=(C.ma[i][j]+(A.ma[i][k]*B.ma[k][j]+mod)%mod)%mod;
    return C;
}
Matrix pow_mod() {
    int len = strlen(s);
    for (int i = len - 1; i >= 0; i--) {
        Matrix C = E;
        int a = s[i] - '0';
        for (int j = 1; j <= 9; j++) {
            if (j == a) A = mul(E,A);
            E = mul(E ,C);
        }
    }
    return A;
}
int main() {
    scanf("%lld%lld%lld%lld%s%lld",&A.ma[1][0],&A.ma[0][0],&E.ma[0][0],&E.ma[0][1],s,&mod);
    E.ma[1][0] = 1;
    A = pow_mod();
    printf("%lld\n", A.ma[1][0]);
    return 0;
}
View Code

 

 

G.subsequence 1

Portal

Meaning of the questions: Tell you two digits of a string s, t, s and asked how many sub-string digital sequence represented by numbers than t represented large. (Both without leading 0)

Solution: When the sequence is longer than the length s t, T is clearly larger than that; when the sequence length is equal to t, we can be solved by dynamic programming. We DP [i] [j] be the i-th and represented before the same number of strings before t s j-th program strings. Cycles use two for the i-th sequence s is determined as the magnitude relationship between the j-th bit string and t: i-1 comprises a front case of the i-th former case, we first dp [i-1] [j] assigned to dp [i] [j], the current s [i] == time t [j], the same number of programs before an i-th and j-th front t s string string plus i- 1 and j-1 the same situation bit dp [i-1] [j -1]; if s [i]> when t [j], before the j-1 position selected case dp [i-1] [ j-1], j-th bit is selected from i, a final mj mj obviously take any and all of the remaining ni meet the characters. Finally, we add the number of sequence length is greater than t does not contain leading zeros can.

Code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3000 + 10;
const ll mod = 998244353;
ll c[N][N],dp[N][N];
char s[N],t[N];
int main() {
    int T,n,m;
    c[1][1] = c[1][0] = c[0][0] = 1;
    for (int i = 2; i <= 3000; i++) {
        c[i][0] = c[i][i] = 1;
        for (int j = 1; j < i; j++)
            c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod;
    }
    for (scanf("%d",&T);T--;) {
        scanf("%d%d%s%s",&n,&m,s+1,t+1);
        dp[0][0] = 1;
        ll ans = 0;
        for (int i = 1; i <= n; i++) {
            dp[i][0] = 1;
            for (int j = 1; j <= min(m,i); j++) {
                dp[i][j] = dp[i-1][j];
                if (s[i] == t[j]) dp[i][j] = (dp[i][j]+dp[i-1][j-1])%mod;
                else if (s[i] > t[j]) {
                    ans = (ans + c[n-i][m-j] * dp[i-1][j-1]%mod)%mod;
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            if (s[i] == '0') continue;
            for (int j = m; j <= n-i; j++) 
                ans = (ans + c[n-i][j])%mod;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
View Code

 

 

H.subsequence 2

The meaning of problems: there is a length of n, m different string of characters, you m * (m-1) / 2 sets of data, to the first line of each two characters, the string given that this a total number of two characters, then the order of the characters appearing in the string output. Ask if you can find qualified string, can not, then output -1 can then easily output a qualifying string.

Solution: We can use this string as a map, based on each character type and it is the first of several to give it a number, and then contextually construction side, and finally get the sequence by sequence topology. -1 outputs to be noted that n is not equal to the number of characters or a sequence number of the topology is not equal to n is obtained.

Code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e4 + 10;
char c[5],s[N],t[N];
vector<int> V[N*30];
int num[30],du[N*30];
int n,m,len;
bool topo() {
    queue<int> q;
    for (int i = 0; i < 26; i++) 
        if(num[i]>0 && du[i*10001+1] == 0)
            q.push(i*10001+1);
    int cnt = 0;
    while(q.size()){
        int u = q.front();
        q.pop();
        s[cnt++] = (u-1)/10001 + 'a';
        if (cnt > n) return false;
        for (int i = 0; i < V[u].size(); i++) 
            if (--du[V[u][i]] == 0)  q.push(V[u][i]);
    }
    s[cnt] = '\0';
    if (cnt == n) return true;
    return false;
}
int main() {
    scanf("%d%d",&n,&m);
    m = m*(m-1)/2;
    for (int i = 0; i < m; i++) {
        scanf("%s%d",c,&len);
        if (len == 0) continue;
        scanf("%s",t);
        int num0 =  0, num1 = 0,fst = 0, id;
        for (int j = 0; j < len; j++) {
            if (t[j] == c[0]) {
                num0++;
                id = (t[j]-'a')*10001 + num0;
            }else {
                num1++;
                id = (t[j]-'a')*10001 + num1;
            }
            if (fst) {
                du[id]++;
                V[fst].push_back(id);
            }
            fst = id;
        }
        if (!num[c[0]-'a']) num[c[0]-'a'] = num0;
        if (!num[c[1]-'a']) num[c[1]-'a'] = num1;
    }
    int all = 0;
    for (int i = 0; i < 26; i++) all += num[i];
    if (all != n) printf("-1\n");
    else if (topo()) printf("%s\n", s);
    else printf("-1\n");
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/l999q/p/11290578.html