Codeforces Round #566 (Div. 2)

C. Beautiful Lyricsnode

題意:ios

定義「優美的歌詞」以下:c++

  • 由兩行四個單詞組成,每行兩個,用空格隔開git

  • 第一行第一個單詞的元音數等於第二行第一個單詞的元音數ide

  • 第一行第二個單詞的元音數等於第二行第二個單詞的元音數ui

  • 每行的最後一個出現的元音相同spa

給定nn個單詞,保證每一個單詞含有至少一個元音。每一個輸入的單詞只能使用一次,重複輸入按輸入次數記。blog

請找到最大的mm,並構造一個含有mm段「優美的歌詞」方案。ci

 

很是麻煩的模擬題  比較考驗碼力  比賽的時候一個半小時才寫出了QAQget

具體沒啥好說的  強行模擬便可   先篩兩遍

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=1e6+5;
int n;
struct node
{
    int num,last;
    string str;
}s[N],s1[N],s2[N];
 
bool cmp(node a,node b)
{
    return a.num>b.num||a.num==b.num&&a.last<b.last;
}
 
int cnt1,cnt2,cnt3;
int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>n;
    rep(i,1,n)
    {
        cin>>s[i].str;
        int len=s[i].str.size();
        rep(j,0,len-1)
        {
            if(s[i].str[j]=='a')
            s[i].num++,s[i].last=1;
            else if(s[i].str[j]=='e')
            s[i].num++,s[i].last=2;
            else if(s[i].str[j]=='i')
            s[i].num++,s[i].last=3;
            else if(s[i].str[j]=='o')
            s[i].num++,s[i].last=4;
            else if(s[i].str[j]=='u')
            s[i].num++,s[i].last=5;
        }
    }
    sort(s+1,s+1+n,cmp);
 
    rep(i,1,n)
    {
        if(s[i].num==s[i+1].num&&s[i].last==s[i+1].last)
        {
            s1[++cnt1]=s[i];
            s1[++cnt1]=s[i+1];
            i++;
        }
        else if(s[i].num)
        {
            s2[++cnt2]=s[i];
        }
 
    }
    sort(s2+1,s2+1+cnt2,cmp);
    rep(i,1,cnt2)
    {
        if(s2[i].num==s2[i+1].num&&s2[i].num)
        {
            s[++cnt3]=s2[i];
            s[++cnt3]=s2[i+1];
            i++;
        }
    }
    cnt2=cnt3;
    if(cnt2>=cnt1)cout<<cnt1/2;
    else cout<<cnt2/2+(cnt1-cnt2)/4  ;
    cout<<endl;
 
    if(cnt2>=cnt1)
    {
        rep(i,1,cnt1)
        {
            cout<<s[i].str<<" "<<s1[i].str<<endl;
            cout<<s[i+1].str<<" "<<s1[i+1].str<<endl;
            i++;
        }
    }
    else
    {
        rep(i,1,cnt2)
        {
            cout<<s[i].str<<" "<<s1[i].str<<endl;
            cout<<s[i+1].str<<" "<<s1[i+1].str<<endl;
            i++;
        }
        rep(i,cnt2+1,cnt1)
        {
            if(i+3>cnt1)break;
            cout<<s1[i+3].str<<" "<<s1[i].str<<endl;
            cout<<s1[i+2].str<<" "<<s1[i+1].str<<endl;
            i+=3;
        }
    }
 
    return 0;
}
View Code

 

 

E.Product Oriented Recurrence

這是一道矩陣加速的好題  我以前只會加法的  這個是乘法的  要把乘法轉化爲加法

 

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
 
template <class T>
inline void read(T &x) {
    x = 0;
    char c = getchar();
    bool f = 0;
    for (; !isdigit(c); c = getchar()) f ^= c == '-';
    for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    x = f ? -x : x;
}
 
template <class T>
inline void write(T x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    T y = 1;
    int len = 1;
    for (; y <= x / 10; y *= 10) ++len;
    for (; len; --len, x %= y, y /= 10) putchar(x / y + 48);
}
 
const LL MOD = 1e9 + 7, PHI = 1e9 + 6;
LL n, f1, f2, f3, c, ans;
 
struct Matrix {
    int size;
    LL mat[6][6];
 
    Matrix(int x) {
        size = x;
        memset(mat, 0, sizeof (mat));
    }
    inline friend Matrix operator*(Matrix a, Matrix b) {//矩陣乘法 
        Matrix c(a.size);
        for (int i = 1; i <= c.size; ++i)
            for (int k = 1; k <= c.size; ++k)
                for (int j = 1; j <= c.size; ++j)
                    c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % PHI;
                    //這裏對 φ(p) 取模 
        return c;
    }
} baseA(3), x(3), y(3), z(3), baseB(5), w(5);
 
inline LL quickPow(LL x, LL p) {//快速冪 
    LL res = 1;
    for (; p; p >>= 1, x = x * x % MOD)
        if (p & 1) res = res * x % MOD;
    return res;
}
 
inline Matrix quickPow(Matrix x, LL p) {//矩陣快速冪 
    Matrix res(x.size);
    for (int i = 1; i <= res.size; ++i) res.mat[i][i] = 1;//單位矩陣 
    for (; p; p >>= 1, x = x * x)
        if (p & 1) res = res * x;
    return res;
}
 
inline void build() {//構造初始矩陣和轉移矩陣 
    x.mat[3][1] = y.mat[2][1] = z.mat[1][1] = 1;
    w.mat[5][1] = 2;
    baseA.mat[1][1] = baseA.mat[1][2] = baseA.mat[1][3] = 
    baseA.mat[2][1] = baseA.mat[3][2] = 1;//baseA 是 x,y,z 的轉移矩陣 
    for (int i = 1; i <= 5; ++i) baseB.mat[1][i] = 1;
    baseB.mat[2][1] = baseB.mat[3][2] = baseB.mat[4][4] = 
    baseB.mat[4][5] = baseB.mat[5][5] = 1;//baseB 是 w 的轉移矩陣 
}
 
int main() {
    read(n), read(f1), read(f2), read(f3), read(c);
    build();
    baseA = quickPow(baseA, n - 3), baseB = quickPow(baseB, n - 3);
    w = baseB * w, x = baseA * x, y = baseA * y, z = baseA * z;
    //求出四個答案矩陣後獲得 w[n],x[n],y[n],z[n]
    ans = quickPow(c, w.mat[1][1]) * quickPow(f1, x.mat[1][1]) % MOD * 
    quickPow(f2, y.mat[1][1]) % MOD * quickPow(f3, z.mat[1][1]) % MOD;
    //快速冪合併答案 
    write(ans);
    putchar('\n');
    return 0;
}
View Code
相關文章
相關標籤/搜索