HDU 5229 ZCC loves strings 博弈

題目連接:

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 */
相關文章
相關標籤/搜索