hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5229php
bc:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=582&pid=1002ios
設字符串a,b;spa
結論:先手勝的充分必要條件是|a|+|b|爲奇數或a==b。code
證實:blog
數學概括法:ci
|a|+|b|=0;時,先手敗,結論成立字符串
假設|a|+|b|<p時結論成立,如今分類討論|a|+|b|的狀況:get
p爲偶數:數學
若是a=b,則先手直接採起方案b取勝,不然,先手只能執行方案A必敗。string
p爲奇數:
先手只要用方案a取走一個,且保證取走以後a!=b(取較短的那個,當較短爲0時,去另外一個),那麼就能保證必勝。
綜上所述,結論成立。
---------------------------------我是分割線----------------------------------
對於當前輸入串,統計它以前與它相等的串的個數x和長度與它不一樣奇偶的串的個數y,累加它對答案的貢獻x+y,線性掃一遍就行了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<map> 5 using namespace std; 6 7 const int maxn=1e5+10; 8 9 int odd[2]; 10 char str[maxn]; 11 int n; 12 map<string,int> mymap; 13 14 void init(){ 15 mymap.clear(); 16 memset(odd,0,sizeof(odd)); 17 } 18 19 int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } 20 21 int main(){ 22 int tc; 23 scanf("%d",&tc); 24 while(tc--){ 25 init(); 26 int ans=0; 27 scanf("%d",&n); 28 for(int i=0;i<n;i++){ 29 scanf("%s",str); 30 int o=strlen(str)&1; 31 ans+=odd[!o]; 32 odd[o]++; 33 34 //str不須要是string類型! 35 ans+=mymap[str]; 36 mymap[str]++; 37 } 38 int demo=n*(n-1)/2; 39 int g=gcd(ans,demo); 40 if(ans==0) printf("0/1\n"); 41 else printf("%d/%d\n",ans/g,demo/g); 42 } 43 return 0; 44 } 45 46 /* 47 2 48 ab 49 bc 50 */