zoukankan      html  css  js  c++  java
  • SRM472

    这次是rng_58出的题目,思维难度还是相当大的的。。很值得一做。

    250pt:

      题意:盒子里有n 个 potatoes,甲乙两个人,每次只能拿4的幂次方数(1,4,16...),最后不能拿的输。求谁赢

     思路:打表找规律。结果是n%5 == 2 || n % 5 == 0 后者赢。否则先者。

    code:

     1 #line 7 "PotatoGame.cpp"
     2 #include <cstdlib>
     3 #include <cctype>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <vector>
     9 #include <string>
    10 #include <iostream>
    11 #include <sstream>
    12 #include <map>
    13 #include <set>
    14 #include <queue>
    15 #include <stack>
    16 #include <fstream>
    17 #include <numeric>
    18 #include <iomanip>
    19 #include <bitset>
    20 #include <list>
    21 #include <stdexcept>
    22 #include <functional>
    23 #include <utility>
    24 #include <ctime>
    25 using namespace std;
    26 
    27 #define PB push_back
    28 #define MP make_pair
    29 
    30 #define REP(i,n) for(i=0;i<(n);++i)
    31 #define FOR(i,l,h) for(i=(l);i<=(h);++i)
    32 #define FORD(i,h,l) for(i=(h);i>=(l);--i)
    33 
    34 typedef vector<int> VI;
    35 typedef vector<string> VS;
    36 typedef vector<double> VD;
    37 typedef long long LL;
    38 typedef pair<int,int> PII;
    39 int sg[15000]; 
    40 
    41 class PotatoGame
    42 {
    43         public:
    44         string theWinner(int n)
    45         {
    46              if (n % 5 == 0 || n % 5 == 2) return "Hanako";
    47              return "Taro";    
    48         }
    49 };
    View Code

    500pt:

    题意:有N<=50张卡片,每张卡片有正方两面,现在题目给定每张卡片的正反两面上的数字(数字为1~n,并且每个数字出现两次),现在求把这n张卡片拿去排列,有多少种结果

    思路:需要知道的知识:

           1、有重复数字的排列:n个数字排列,其中有a个数字出现两次,排列数为:n!/2^a

           2、对于一个长度为n的置换,取出k个数出现2次,有2*C(n, k*2)方案。

          当然,出现置换解题的关键当然就是他了。。

          对于1张卡片,将两边的数字连一条边,那么所有的卡片就会出现若干个环(也就是置换啦)

          那么对于不同的环之间,是不会互相影响的,直接用乘法原理统计

          难点的就是相同环之间,我们就必须枚举出现相同的数的个数,然后结合1和2进行统计即可。对了还要用到乘法逆元。。具体见代码吧。

    code:

        

     1 #line 7 "TwoSidedCards.cpp"
     2 #include <cstdlib>
     3 #include <cctype>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <vector>
     9 #include <string>
    10 #include <iostream>
    11 #include <sstream>
    12 #include <map>
    13 #include <set>
    14 #include <queue>
    15 #include <stack>
    16 #include <fstream>
    17 #include <numeric>
    18 #include <iomanip>
    19 #include <bitset>
    20 #include <list>
    21 #include <stdexcept>
    22 #include <functional>
    23 #include <utility>
    24 #include <ctime>
    25 using namespace std;
    26 
    27 #define PB push_back
    28 #define MP make_pair
    29 
    30 #define REP(i,n) for(i=0;i<(n);++i)
    31 #define FOR(i,l,h) for(i=(l);i<=(h);++i)
    32 #define FORD(i,h,l) for(i=(h);i>=(l);--i)
    33 #define M 1000000007
    34 typedef vector<int> VI;
    35 typedef vector<string> VS;
    36 typedef vector<double> VD;
    37 typedef long long LL;
    38 typedef pair<int,int> PII;
    39 long long dp[1200][50];
    40 long long C[120][120];
    41 int fa[50];
    42 
    43 class TwoSidedCards
    44 {
    45         public:
    46         LL power(LL a, int b){
    47                LL ret = 1;
    48                while (b){
    49                       if (b & 1) ret = (ret * a) % M;
    50                       a = (a * a) % M;
    51                       b >>= 1;
    52                }
    53                return ret;
    54         }
    55         int find(int k){
    56              if (fa[k] == k) return k;
    57              return fa[k] = find(fa[k]);
    58         }
    59         long long permCount(int n){
    60               LL ret = 0;
    61               for (int i = 2; i <= n; i += 2)
    62                    ret = (ret + C[n][i] * power(power(2, i / 2 - 1), M - 2)) % M;
    63               ret =(ret + C[n][0]) % M;
    64               for (int i = 1; i <= n; ++i)
    65                    ret = (ret * i) % M;
    66               return ret;        
    67         }
    68         int theCount(vector <int> taro, vector <int> hanako)
    69         {
    70                 for (int i = 0; i <= 50; ++i){
    71                       C[i][0] = 1;
    72                       for (int j = 1; j <= i; ++j) C[i][j] = (C[i-1][j-1] + C[i-1][j]) % M;
    73                 }
    74                 int n = taro.size(), m = taro.size();
    75                 for (int i = 0; i <= n; ++i) fa[i] = i;
    76                 for (int i = 0; i < n; ++i){
    77                      int x = taro[i], y = hanako[i];
    78                      int fx = find(x), fy = find(y);
    79                      if (fx != fy) fa[fx] = fy;
    80                 }
    81                 long long ret = 1;
    82                 for (int i = 1; i <= n; ++i) find(i);
    83                 for (int i = 1; i <= n; ++i) if (fa[i] == i){
    84                          int s = 0;
    85                          for (int j = 1; j <= n; ++j)
    86                               if (fa[j] == i) ++s;
    87                          ret = (ret * C[m][s]) % M;
    88                          m -= s;
    89                          ret = (ret * permCount(s)) % M;
    90                }
    91                return ret; 
    92         }
    93  };      
    View Code

    code:

  • 相关阅读:
    cvCreateStructuringElementEx理解
    GNU_GSL相关
    粒子滤波(转)
    C++指针拷贝
    c++中的复制构造函数
    通过几道题目找自信
    C++网络编程基础
    linux system : install flash player
    ContentType一览
    O_RDWR O_CREAT等open函数标志位在哪里定义?(格式还要编译,答案在最后一段)
  • 原文地址:https://www.cnblogs.com/yzcstc/p/3626888.html
Copyright © 2011-2022 走看看