hdu 5229 ZCC loves strings(Bestcoder Round #41)

ZCC loves strings

                                                      Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Others)

Total Submission(s): 286    Accepted Submission(s): 108

Problem Description

ZCC has got N strings. He is now playing a game with Miss G.. ZCC will pick up two strings among those N strings randomly(A string can‘t be chosen twice). Each string has the same probability to be chosen. Then ZCC and Miss G. play in turns. Miss G. always
plays first. In each turn, the player can choose operation A or B.

Operation A: choose a non-empty string between two strings, and delete a single letter at the end of the string.

Operation B: When two strings are the same and not empty, empty both two strings.

The player who can‘t choose a valid operation loses the game.

ZCC wants to know what the probability of losing the game(i.e. Miss G. wins the game) is.

Input

The first line contains an integer T(T≤5) which
denotes the number of test cases.

For each test case, there is an integer N(2≤N≤20000) in
the first line. In the next N lines, there is a single string which only contains lowercase letters. It‘s guaranteed that the total length of strings will not exceed 200000.

Output

For each test case, output an irreducible fraction "p/q" which is the answer. If the answer equals to 1, output "1/1" while output "0/1" when the answer is 0.

Sample Input

1
3
xllendone
xllendthree
xllendfour

Sample Output

2/3

官方题解

结论:对于串a和b,游戏中先手必胜当且仅当|a|+|b|为奇数或a=b.
我们按|a|+|b|的大小从小到大考虑所有的情况。
当|a|+|b|=0时,显然先手必败,符合结论。
假设已经证明了|a|+|b|=k(k<p)的所有情况满足结论,现在考虑|a|+|b|=p的情况。
若p是奇数,先手只需要选择长度较短的不为空的串,并使用A操作,就可以转移到|a|+|b|为偶数并且两个串不相等或者两个串均为空的情况,这种情况先手必败,故此时先手必胜。
若p是偶数,如果两个串相等,显然先手只需要选择使用B操作就能获得胜利了。否则,无论先手如何操作,都只能转移到|a|+|b|为奇数的先手必胜的情况。故此时先手必败。
因此,按顺序考虑每一个串,求得在其之前出现的串中,长度奇偶性与其不同的串共有x个,与其完全相同的串有y个,则对答案有x+y的贡献。累加即可。
PS:游戏者都是按照最优策略操作的,所以当两个字符串的和为奇数时,先手只需每次都先取字符串较短的字符
    串,就不会出现相同的字符串,所以两个字符串的和为奇数时,先手必胜。统计奇偶与其不同的只需记录一
    前面有多少与其不同的就可,与其相同的字符串用map来统计与其相同的字符串出现多少次,一个出现x次 
    的字符串,对答案的贡献是x*(x-1)/2
代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
map<string,int> mp;
int gcd(int n,int m)
{
    if(m==0)
    return n;
    else
    return gcd(m,n%m);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        mp.clear();
        int n;
        scanf("%d",&n);
        int odd=0,even=0;
        string s;
        int ans=0;
        for(int i=0;i<n;i++)
        {
            cin>>s;
            mp[s]++;
            if(s.size()%2)
            {
                odd++;
                ans+=even;
            }
            else
            {
                even++;
                ans+=odd;
            }
        }
        map<string,int>::iterator it;
        for(it=mp.begin();it!=mp.end();it++)
        {
            int cur=it->second;
            ans+=(cur*(cur-1))/2;
        }
        int all=n*(n-1)/2;
        int gd=gcd(ans,all);
        printf("%d/%d\n",ans/gd,all/gd);
    }
    return 0;
}

时间: 2024-10-18 18:09:16

hdu 5229 ZCC loves strings(Bestcoder Round #41)的相关文章

HDU 5228 ZCC loves straight flush( BestCoder Round #41)

题目链接:pid=5228">ZCC loves straight flush pid=5228">题面: pid=5228"> ZCC loves straight flush Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 827    Accepted Submission(s): 340

hdu 5229 ZCC loves strings

题意: CC有N个字符串,他正在和Miss G.用这N个字符串玩一个小游戏.ZCC会从这N个串中等概率随机选两个字符串(不可以是同一个).然后,ZCC和Miss G.轮流操作.Miss G.总是先操作的.在每轮中,操作者可以选择操作A或操作B. 操作A:在两个串中选择一个当前非空的串,然后在这个串的末尾删去一个字符. 操作B: 若当前两个串完全相同且非空,则可以使用这个操作.此时两个串都被清空. 不能操作的玩家输掉了这个游戏. ZCC想要知道他输掉游戏的概率是多少(也就是Miss G.获胜的概率

HDU 5805 - NanoApe Loves Sequence (BestCoder Round #86)

先找相邻差值的最大,第二大,第三大 删去端点会减少一个值, 删去其余点会减少两个值,新增一个值,所以新增和现存的最大的值比较一下取最大即可 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 using namespace std; 5 #define LL long long 6 const int N = 100005; 7 int t, n, p1, p2, p3; 8 LL a[N]; 9

HDU 5806 - NanoApe Loves Sequence Ⅱ (BestCoder Round #86)

若 [i, j] 满足, 则 [i, j+1], [i, j+2]...[i,n]均满足 故设当前区间里个数为size, 对于每个 i ,找到刚满足 size == k 的 [i, j], ans += n - j + 1 . i++ 的时候看看需不需要size-- 就可以更新了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 #define

hdu 4882 ZCC Loves Codefires(数学题+贪心)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4882 ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

HDU 4873 ZCC Loves Intersection(JAVA、大数、推公式)

在一个D维空间,只有整点,点的每个维度的值是0~n-1 .现每秒生成D条线段,第i条线段与第i维度的轴平行.问D条线段的相交期望. 生成线段[a1,a2]的方法(假设该线段为第i条,即与第i维度的轴平行)为,i!=j时,a1[j]=a2[j],且随机取区间[0,n-1]内的整数.然后a1[i],a2[i]在保证a1[i]<a2[i]的前提下同样随机. 由于D条线段各自跟自己维度的轴平行,我们可以转换成只求第i个维度与第j个维度的相交期望,然后乘以C(2,n)就好了 显然线段[a1,a2]和线段[

hdu 4882 ZCC Loves Codefires(贪心)

# include<stdio.h> # include <algorithm> # include <string.h> using namespace std; struct node { int v; int t; }; struct node a[100010]; bool cmp(node a,node b) { return a.v *a.t+(a.v+b.v)*b.t<b.v*b.t+(a.v+b.v)*a.t; } int main() { int

HDU 4876 ZCC loves cards(暴力剪枝)

HDU 4876 ZCC loves cards 题目链接 题意:给定一些卡片,每个卡片上有数字,现在选k个卡片,绕成一个环,每次可以再这个环上连续选1 - k张卡片,得到他们的异或和的数,给定一个L,问能组成[L,R]所有数字的情况下,R的最大值是多少 思路:暴力C(20, 6),然后对于每个序列去全排后模拟计算值, 不过之前要有个剪枝,全排前,先把k个数随机取数(即不用连续),然后如果这样还满足不了,那么连续的情况肯定也满足不了,直接结束,不进入全排.这样一来由于满足不了的情况实际上是占绝大

HDU 4932 Miaomiao&#39;s Geometry(BestCoder Round #4)

Problem Description: There are N point on X-axis . Miaomiao would like to cover them ALL by using segments with same length. There are 2 limits: 1.A point is convered if there is a segments T , the point is the left end or the right end of T.2.The le