zoukankan      html  css  js  c++  java
  • 方程的解数

                                                                                                                                                                     题目在这里呀

    题目:

      已知一个n元高次方程:

      其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数。
      假设未知数1 <= xi <= M, i=1…n,求这个方程的整数解的个数。
      1 <= n <= 6;1 <= M <= 150。

      方程的整数解的个数小于2 31

         (本题中,指数Pi(i=1,2,...,n)均为正整数。)

    思路:

      最简单的dfs 当然就是枚举每个k,p所对应的x 然后check 更新ans

      但是  这一定是会TLE的 因为复杂度是 150的6次方

      要注意 Xi  X是有下标的 说明是不同的X !

    正解是:

      把式子分为两个部分 分别dfs求出两个部分的所有可能值 

      这样子搜索的复杂度就变成150的3次方再*2了

            然后排个序 计算出两个式子相加为0的方案数 即 解的总数

      我用的是一一匹配的方法 (是我自己取的名字qwq)

            好像还可以用map 或者hash完成这一步 但是 我并不会qwq 

      还可以加快速幂优化一下呀 (今天写快速幂居然写错了) 这里是快速幂

         

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define go(i,u,v) for(register int i=u;i<=v;i++)
     5 #define M 3375001
     6 using namespace std;
     7 int read()
     8 {
     9   int x=0,y=1;char c=getchar();
    10   while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();}
    11   while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    12   return x*y;
    13 }
    14 int k[10],p[10],n,m,d1[M],d2[M],n1,n2,t1,t2,ans;
    15 int ksm(int x,int y) 
    16 {
    17   int s=1;
    18   while(y>0) {if(y&1) s*=x;x*=x;y>>=1;}
    19   return s;
    20 }
    21 void dfs1(int now,int sum)
    22 {
    23   if(now>n1) {d1[++t1]=sum;return ;}
    24   go(i,1,m) dfs1(now+1,sum+k[now]*ksm(i,p[now]));
    25 }
    26 void dfs2(int now,int sum)
    27 {
    28   if(now>n2) {d2[++t2]=sum;return ;}
    29   go(i,1,m) dfs2(now+1,sum+k[now+n1]*ksm(i,p[now+n1]));
    30 }
    31 void work()
    32 {
    33   int r=t2;
    34   sort(d1+1,d1+t1+1);sort(d2+1,d2+t2+1);
    35   go(l,1,t1) {
    36     int s1=1,s2=1;
    37     while(d1[l]+d2[r]>0&&r>0) r--;
    38     if(!r) break ;
    39     if(d1[l]+d2[r]!=0) continue ;
    40     while(d1[l+1]==d1[l]&&l<t1) s1++,l++;
    41     while(d2[r-1]==d2[r]&&r>0) s2++,r--;
    42     ans+=s1*s2;
    43   }
    44 }
    45 int main()
    46 {
    47   n=read();m=read();n1=n/2;n2=(n+1)/2;
    48   go(i,1,n) k[i]=read(),p[i]=read();
    49   dfs1(1,0);dfs2(1,0);
    50   work();printf("%d",ans);
    51   return 0;
    52 } 
    View Code
    光伴随的阴影
  • 相关阅读:
    iOS学习——键盘弹出遮挡输入框问题解决方案
    知识扩展——Git和GitHub的区别
    iOS项目——项目开发环境搭建
    iOS学习——iOS项目Project 和 Targets配置详解
    iOS扩展——Objective-C开发编程规范
    iOS学习——Xcode9上传项目到GitHub
    Mac OS Sierra如何打开任何来源
    iOS学习——UIAlertController详解
    iOS学习——获取iOS设备的各种信息
    Drag and drop folder to a TextBox in C#
  • 原文地址:https://www.cnblogs.com/forward777/p/10307615.html
Copyright © 2011-2022 走看看