ZCC loves strings
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 343 Accepted Submission(s): 131
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.
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.
題意:有n個字符串,從這裏面隨機選擇兩個字符串。然後兩個人輪流操作,有兩種操作:
1,如果兩個字符串相同,可以刪除這兩個字符串。
2,選擇一個字符串,刪掉最後一個字符。
第一個不能操作的人輸。
對於先手來說:
如果兩個串相同,則先手贏
否則,由於兩個人都採用最優策略,則兩個串相同的情況一定不會出現,那麼如果兩個串的總共有奇數個字符則先手贏,否則先手輸。
那麼我們只需要統計奇數串和偶數串的個數,以及相同的串的個數就行了。
代碼如下:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<vector>
#define inff 0x3fffffff
#define nn 21000
#define mod 1000000007
typedef __int64 LL;
typedef unsigned __int64 LLU;
const LL inf64=inff*(LL)inff;
using namespace std;
int n;
map<string,int>ma;
char s[nn*10];
int gcd(int x,int y)
{
if(y==0)
{
return x;
}
return gcd(y,x%y);
}
int main()
{
int t,i;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
ma.clear();
int ix,fc;
ix=fc=0;
int ans=0;
for(i=1;i<=n;i++)
{
scanf("%s",s);
int ls=strlen(s);
if(ls%2)
ix++;
else
fc++;
if(ma.count(s)==0)
{
ma[s]=1;
}
else
{
ans+=ma[s];
ma[s]++;
}
}
ans+=ix*fc;
if(ans==0)
{
puts("0/1");
continue;
}
int tem=gcd(ans,(n-1)*n/2);
printf("%d/%d\n",ans/tem,(n-1)*n/2/tem);
}
return 0;
}