URAL - 1932

Davy Jones: You've been captain of the Black Pearl for 13 years. That was our agreement. 
Jack: Technically I was only captain for two years, then I was mutinied upon. 
 Davy Jones: Then you were a poor captain, but a captain nonetheless. Have you not introduced yourself as Captain Jack Sparrow?
According to the Pirate Code, each of the pirates of the Caribbean at the beginning of their professional career (hereditary pirates –– at birth) is assigned by a unique identifier. Pirate's identifier is a string of four hexadecimal digits. However, it is not a usual row of numbers, it is said that personal qualities and life path of its owner are encoded in it by a mysterious way. But no one still could guess this mystical connection.
Once Captain Jack Sparrow, while sitting in captain’s cabin, decided to try to find the way to derive some data about a pirate using the identifier. Memories about how he lost the Black Pearl last time gave him the idea that more similar identifiers of two pirates are, bigger chances for these pirates to unite against the Captain, and, as a result, to make a mutiny. The Captain Jack Sparrow, of course, doesn’t want to have the mutiny on his ship, but he chose the new team this time and it is going to be a long voyage. Now Jack needs to estimate the opportunities of raising the mutiny on his ship, based on the conclusions. For this aim he first wants to know for each pair of pirates a number of positions in their identifiers in which they are different.
Input
The first line contains an integer  n –– the number of pirates aboard the Black Pearl (2 ≤  n ≤ 65536). Each of the following  n lines contains four-digit identifier of the respective pirate. Only decimal digits and lowercase Latin letters from “a” to “f” inclusive are used in writing identifiers. Identifiers of all pirates are different.
Output
Output four space separated integers –– the amount of pairs of pirates, which have different identifiers exactly in one, two, three and four positions respectively.
Example
input output
3
dead
beef
f00d


补集思想,然后把每个串的子串的状态枚举出来。然后统计一下。

最后容斥去重。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>

using namespace std;
const int MAXN = 5e4+7;
const long long inf = 2e18;
int n;
long long ans[5],temp[5];
long long sum[16][1<<16];
int change(char c)
{
    if(isalpha(c))return c - 'a' + 10;
    else return c - '0';
}
int get_num(int x)
{
    int ret = 0;
    while(x)
    {
        if(x & 1)ret++;
        x >>= 1;
    }
    return ret;
}


char s[5];
int main()
{
    scanf("%d",&n);
    int max_state = 0;
    for(int i = 0 ; i < n ;++i)
    {
        scanf("%s",s);
        for(int k = 1 ; k < 16 ; ++k)
        {
            int t = 0;
            if(k & 8)t += change(s[0])*(1<<12);
            if(k & 4)t += change(s[1])*(1<<8);
            if(k & 2)t += change(s[2])*(1<<4);
            if(k & 1)t += change(s[3]);
            sum[k][t]++;
            max_state = max(max_state,t);
        }
    }
    for(int k = 1 ; k < 16 ; ++k)
    {
        int x = get_num(k);
        for(int j = 0 ; j <= max_state ; ++j)
        {
            temp[x] += sum[k][j]*(sum[k][j] - 1)/2;
        }
    }
    ans[1] = temp[3];
    ans[2] = temp[2] - temp[3]*3;
    ans[3] = temp[1] - temp[2]*2 + temp[3]*3;
    ans[4] = (long long)n*(n-1)/2 - ans[1] - ans[2] - ans[3];
    printf("%I64d %I64d %I64d %I64d\n",ans[1],ans[2],ans[3],ans[4]);

    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值