zoukankan      html  css  js  c++  java
  • HDU6415 Rikka with Nash Equilibrium

    HDU6415 Rikka with Nash Equilibrium

    找规律 + 大数

    由于规律会被取模破坏,所以用了java

    找出规律的思路是:

    对于一个n*m的矩阵构造,我先考虑n*1的构造,很容易知道它是n!种方法。然后对于n*2的矩阵构造,就是在n*1的矩阵中新加入n个元素的排列组合,当然这里面一定会有非法的情况。通过打表可以暴力的搜出5*5以内的答案,所以我就可以知道从n*1的矩阵扩展到n*2的矩阵中有多少种非法组合(n <= 5 只知道小数据)。同理对于n*2扩展到n*3以后到n*(m-1)扩展到n*m的正确方案数和每次剔除的方案数就可以得到(小数据暴力得到)。然后发现规律 每次正确合法方案数:非法方案数 = i :(n-1);i从2迭代到m就可以得到答案。

    java版本:

    //package acm;
    
    import java.math.BigInteger;
    import java.awt.Container;
    import java.math.*;
    import java.math.BigInteger;
    import java.util.*;
    
    import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID; 
    public class Main
    {    
         
        
           public static void main(String[] args) 
           {            
               Scanner cin=new Scanner(System.in);
               int t = cin.nextInt();
               for(int i=1;i<=t;i++)
               {
                   int n = cin.nextInt();
                   int m = cin.nextInt();
                   BigInteger k = cin.nextBigInteger();
                   
                   if(n==1)
                   {
                       BigInteger ans = BigInteger.ONE;
                       for(int j=1;j<=m;j++)
                       {
                           ans = ans.multiply(BigInteger.valueOf(j));
                       }
                       ans = ans.mod(k);
                       System.out.println(ans);
                   }
                   else {
                       BigInteger ans1 = BigInteger.ONE;
                       for(int j=1;j<=n;j++)
                       {
                           ans1 = ans1.multiply(BigInteger.valueOf(j));
                       }
                       
                       //System.out.println(ans1);
                       for(int j=2;j<=m;j++)
                       {
                           BigInteger tt = BigInteger.valueOf(j*n);
                           BigInteger temp = BigInteger.ONE;
                           for(int kk=0;kk<n;kk++)
                           {
                               temp = temp.multiply(tt.subtract(BigInteger.valueOf(kk)));
                           }
                           ans1 = ans1.multiply(temp);
                           ans1 = ans1.multiply(BigInteger.valueOf(j)).divide(BigInteger.valueOf(j+n-1));
                           
                       }
                       ans1 = ans1.mod(k);
                       System.out.println(ans1);
                   }
               }
               cin.close();
          }
    }
    View Code

     

    这道题也可以用c++来通过对数进行拆分成质数的乘积来记录大数(因为保证了过程中除法都是整除)

    c++版本:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int cnt[10005],prime[10005],tag[70007];
    void init(int n){
        int cnt = 0;
        for(int i = 2;i <= n;++i){
            if(!tag[i]) prime[cnt++] = i;
            for(int j = 0;j < cnt && prime[j] * i <= n;++j){
                tag[i*prime[j]] = 1;
                if(i % prime[j] == 0) break;
            }
        }
    }
    vector<int> V[70005];
    long long mod;
    long long power(long long a,long long k){
        long long ret = 1;
        while(k){
            if(k & 1) ret = ret * a % mod;
            a = a * a % mod;
            k >>= 1;
        }
        return ret;
    }
    
    int main()
    {
        init(7000);
        int T;
        cin >> T;
        for(int i = 0;i < 900;++i){
            for(long long j = 1;j * prime[i] <= 7000;++j){
                V[prime[i]*j].push_back(i);
            }
        }
        while(T--)
        {
            memset(cnt,0,sizeof(cnt));
            int n,m;
            scanf("%d%d%lld",&n,&m,&mod);
            for(int i = n*m;i > 1;--i){
                int siz = V[i].size();
                int tmp = i;
                for(int j = 0;j < siz;++j){
                    while(tmp%prime[V[i][j]] == 0) tmp /= prime[V[i][j]],cnt[V[i][j]]++;
                }
            }
            for(int i = 2;i <= m;++i){
                int tmp = n-1+i;
                int siz = V[tmp].size();
                for(int j = 0;j < siz;++j){
                    while(tmp%prime[V[n-1+i][j]] == 0) tmp /= prime[V[n-1+i][j]],cnt[V[n-1+i][j]]--;
                }
                tmp = i;
                siz = V[tmp].size();
    
                for(int j = 0;j < siz;++j){
                    while(tmp%prime[V[i][j]] == 0) tmp /= prime[V[i][j]],cnt[V[i][j]]++;
                }
            }
            long long ans = 1;
            for(int i = 0;i < 900;++i){
                ans = ans * power(prime[i],cnt[i]) % mod;
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    墨卡托投影坐标系(Mercator Projection)原理及实现C代码
    腾讯2018暑期实习生招聘在线笔试之字符串操作
    基于Python实现matplotlib中动态更新图片(交互式绘图)
    基于8211lib库对s57电子海图的解析和存储
    ArcGIS二次开发AO软件安装破解教程
    【持续更新】.Net 开发中给自己埋下的坑!
    Linux下测试PHP和MySQL是否正确安装
    Linux命令行抓包及包解析工具tshark(wireshark)使用实例解析
    测试Apache服务器及httpd: Could not reliably determine the server's fully qualified domain name解决办法
    CHM Navigation to the webpage was canceled 解决办法
  • 原文地址:https://www.cnblogs.com/solvit/p/9507207.html
Copyright © 2011-2022 走看看