2 条题解

  • 0
    |||
    100:0
  • 2

    拼凑春联(文件I/O)

    因为每一个春联有 66 个间隔,对于每个间隔我们可以认为:不同的记为 00false\text{false}),相同记为 11true\text{true})。一共有 26=642^6=64 种可能,因此先设 6464 个桶,每个桶内,每两个均可能构成春联。

    具体 mm 的实现方式:

    int m=0;
            for (int j=0; j<6; j++)
                m=m*2+(s[j]==s[j+1]);
    

    这样,如果有两个春联是对偶的,那么他们的 mm 最后结果一定相等。孝先,一定要知道这个( 一致性 )。

    然后,我们把它们的结果记在一个 a[m]a[m] 里:

    a[m]++;
    

    我们可以拿样例举例。

    5
    ABCCCDA
    LLLMNNO
    DEZZZBF
    AAABCCD
    KKKXPPQ
    

    a[i]a[i]的每次结果如下:

    0 0 0 0 0 0 0 0 0 0 0 0 1
    0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
    0 0 0 0 0 0 0 0 0 0 0 0 2
    0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2
    0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3
    

    但我们只需要注意最后一行。
    只要 nn 个对联是对偶的,在同一个位置( 一致性 )一定是 nn。之后,我们只需要在这 nn 个数里选 22 个,即 C(n,2)=n(n1)/2\text{C}(n,2)=n*(n-1)/2

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int a[64];
    int main(){
        freopen("couplet.in","r",stdin);
        freopen("couplet.out","w",stdout);
        int n;
        char s[10];
        scanf("%d", &n);
        for (int i=0; i<n; i++){
            scanf("%s", s);
            int m=0;
            for (int j=0; j<6; j++)
                m=m*2+(s[j]==s[j+1]);
            a[m]++;
        } 
        ll ans=0;
        for (int i=0; i<64; i++)
            ans+=1ll*a[i]*(a[i]-1)/2;
        printf("%lld\n", ans);
        return 0;
    }
    
  • 1
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int a[64];
    int main()
    {
        freopen("couplet.in","r",stdin);
        freopen("couplet.out","w",stdout);
        int n;
        char s[10];
        scanf("%d", &n);
        for (int i=0; i<n; i++)
        {
            scanf("%s", s);
            int m=0;
            for (int j=0; j<6; j++)
                m=m*2+(s[j]==s[j+1]);
            a[m]++;
        }
        ll ans=0;
        for (int i=0; i<64; i++)
            ans+=1ll*a[i]*(a[i]-1)/2;
        printf("%lld\n", ans);
        return 0;
    }
    /*
    将所有佳句按如下规则进行归类:
    相邻字母相同的设为0,不同的设为1,则一共有6个间隔,每位可以为0/1
    一共有2^6=64种可能,因此先设64个桶,每个桶内,每两个均可能构成春联
    即组合数C(x,2)=x*(x-1)/2,x为桶内数的个数
    */
    
  • 1

信息

ID
1501
难度
5
分类
字符串 | 枚举 点击显示
标签
递交数
33
已通过
1
通过率
3%
上传者