Algorithm 由456组成的数的总和

Algorithm 由456组成的数的总和,algorithm,math,Algorithm,Math,我们得到三个整数x,y和z。您必须找到所有数字的总和,这些数字的数字仅由4、5和6组成,在十进制表示法中最多有x 4,在十进制表示法中最多有y 5,在十进制表示法中最多有z 6 我正在使用这个概念 我的代码: // fact[i] is i! for(int i=0;i<=x;i++) for(int j=0;j<=y;j++) for(int k=0;k<=z;k++){ int t = i+j+k;

我们得到三个整数x,y和z。您必须找到所有数字的总和,这些数字的数字仅由4、5和6组成,在十进制表示法中最多有x 4,在十进制表示法中最多有y 5,在十进制表示法中最多有z 6

我正在使用这个概念

我的代码:

// fact[i] is i!
    for(int i=0;i<=x;i++)
        for(int j=0;j<=y;j++)
            for(int k=0;k<=z;k++){

           int t = i+j+k;
           if(t==0) continue;
           long ways = fact[t-1];
           long pow = (long) Math.pow(10,t-1);
           long rep=0;
           if(i!=0){
               rep = fact[j]*fact[k];
               if(i>0) rep*=fact[i-1];

              o+= 4*pow*(ways/rep); 
           }

           if(j!=0){
               rep = fact[i]*fact[k];
               if(j>0) rep*=fact[j-1];

              o+= 5*pow*(ways/rep); 
           }

           if(k!=0){
               rep = fact[i]*fact[j];
               if(k>0) rep*=fact[k-1];

              o+= 6*pow*(ways/rep); 
           }

        }
在Python 3中:

def sumcalc(x,y,z):
  if x < 0 or y < 0 or z < 0: return -1
  import itertools
  sum = 0
  for i, j, k in itertools.product(range(x + 1), range(y + 1), range(z + 1)):
    e = (('4' * i) + ('5' * j) + ('6' * k))
    if e:
      perms = [''.join(p) for p in itertools.permutations(e)]  
      for i in set(perms): sum += int(i)
  return sum
def sumcalc(x,y,z):
如果x<0或y<0或z<0:返回-1
进口itertools
总和=0
对于itertools.乘积(范围(x+1)、范围(y+1)、范围(z+1))中的i、j、k:
e=(('4'*i)+('5'*j)+('6'*k))
如果e:
perms=[''。在itertools中为p加入(p)。置换(e)]
对于集合中的i(perms):sum+=int(i)
回报金额
这种方法很简单,可以用于大多数不一定包含类似语法的编程语言(如果有的话)。基本步骤是:

  • 对于给定的整数x、y和z all>=0,为所有组合中的每一个写入一个字符串,忽略“4”从0到x的出现顺序,“5”从0到y的出现顺序以及“6”从0到z的出现顺序。(但是,生成组合的顺序是为了确保完整性。)

  • 对于(1)中生成的每个字符串,生成其字符的所有唯一和非空排列

  • 对于(2)中产生的每个字符串排列,将其转换为整数并将其添加到总和中


  • Python3整数具有无限精度,因此无需拖入Long或BigInteger类型来提高精度。

    编辑:我意识到链接后描述的内容是相同的。我误以为这与几天前出现的一个类似问题有关,这个问题的解决方式完全不同。因此删除了它,但后来取消了删除,因为它可以向OP解释代码中的错误

    这可以作为一个复杂度为O(xyz)的组合问题来解决

    让我们将问题分为两部分:

    第A部分:找出正好由x4、y5s和z6s组成的数字之和。这相当简单:

  • 让数字如下所示:
    \uuuu4\u4\u8_,其中显示的4个字符出现在
    10^k
    位置。其余数字可按
    (x+y+z-1)!/((x-1)!*y!*z!)
    ways。因此,4在该位置贡献的总金额为
    4*10^k*(x+y+z-1)!/((x-1)!*y!*z!)
    这是
    4*x*10^k*(x+y+z-1)!/(x!*y!*z!)

  • 同样,5和6贡献,该职位数字的总贡献为:
    10^k*(x+y+z-1)!/(x!*y!*z!)*(4x+5y+6z)

  • (例如,使用
    x=y=z=1
    并在10^2位置,贡献为
    400*2+500*2+600*2=3000
    (根据示例)。根据计算,贡献为
    100*2!/(1!*1!)*(4+5+6)=3000

  • 因此,(x+y+z)位数的总体贡献为:
  • (x+y+z-1)!/(x!*y!*z!)*(4x+5y+6z)*(10^0+10^1+…+10^(x+y+z-1))

    =(x+y+z-1)!/(x!*y!*z!)*(4x+5y+6z)*(10^(x+y+z)-1)/9

    因此,在上述示例中,所有3位数字的总和应为:
    2!/(1!*1!*1!)*(4+5+6)*(999)/9=3330
    。 根据示例,它是:
    456+465+546+564+645+654=3330

    第二部分:

  • 执行与上面相同的操作,但x y和z分别取0-x、0-y和0-z的值。这可以通过(0..x)、(0..y)、(0..z)端点(含)中的三向嵌套循环来完成。在每次迭代中使用上述公式

  • 对于上面的例子,我们有x:0-1,y:0-1,z:0-1。可能的索引是{(0,0,0)、(0,0,1)、(0,1,0)、(0,1,1)、(1,0,0)、(1,0,1)、(1,1,0)、(1,1,1)}。根据上述公式计算的两位数的总和为,例如:

    (0,1,1):1/(0! * 1! * 1!) * (5+6) * 99/9 = 121 (1, 0, 1): 1!/(1! * 0! * 1!) * (4+6) * 99/9 = 110 (1, 1, 0): 1!/(1!*1!*0!)*(4+5)*99/9=99

  • 加起来就是330。 在示例中,
    45+54+56+65+46+64=330

    同样,对于给出15的单位。因此,总金额为
    15+330+3330=3675

    注意:

  • 以上可以推广到链接问题和任意位数(不要求数字是连续的)。如果数字中有零,则必须稍微调整该方法,但基本原理是相同的

  • 你可以使用类似的技术计算出从100万到100万的7的数量,这是一个强大的组合方法


  • Python3中的解决方案,它使用重复排列算法。可以适应其他情况,因为输入是一个字典,其中键是请求的数字,值是每个数字的计数

    算法说明: 您可以将排列视为一棵树,其中根包含一个长度为零的数字,其子节点表示1位数字,下一级有2位数字等。每个节点有3个子节点,表示父节点的值扩展了一位数字。因此,该算法基本上是一个预排序树遍历。每次递归调用都会得到当前的数字和要添加的数字(在字典中维护,数字作为键,计数作为值)。它在字典上迭代,依次添加每个可能的数字,然后以新数字和剩余数字递归。该方法还返回开头的当前数字,然后执行所述递归

    #!/usr/bin/env python3
    
    import itertools
    import copy
    
    class Matrix:
      def __init__(self, dim):
        m=None
        for i in dim:
          m=[copy.deepcopy(m) for j in range(i)]
        self.mat=m
      def getVal(self, coord):
        m=self.mat
        for i in coord:
          m=m[i]
        return m
      def setVal(self, coord, val):
        m=self.mat
        l=coord.pop()
        for i in coord:
          m=m[i]
        coord.append(l)
        m[l]=val
    
    def sumOfNumbers(digits):
      def _sumOfNumbers(counts):
        max_v=-1
        for v in counts:
          if v<0:
            return (0,0)
          elif v>max_v:
            max_v=v
        if m.getVal(counts)==None:
          c=0
          s=0
          if max_v==0:
            c=1
          else:
            for i, d in enumerate(digits.keys()):
              counts[i]-=1
              r=_sumOfNumbers(counts)
              counts[i]+=1
              c+=r[0]
              s+=r[1]*10+r[0]*d
    
          m.setVal(counts, (c,s))
        return m.getVal(counts)
    
      dim=[v+1 for v in digits.values()]
      m=Matrix(dim)
      tot_val=0
      for i in itertools.product(*map(lambda x: range(x), dim)):
        r=_sumOfNumbers(list(i))
        tot_val+=r[1]
    
      return tot_val
    
    def main():
      x=1
      y=1
      z=1
      print(x,y,z)
      print(sumOfNumbers({4: x, 5: y, 6: z}))
    
    if __name__ == "__main__":
      main()
    
    #/usr/bin/env蟒蛇3
    进口itertools
    导入副本
    类别矩阵:
    def u u初始(自,dim):
    m=无
    对于我在dim中:
    m=[copy.deepcopy(m)表示范围(i)内的j]
    self.mat=m
    def getVal(自我、合作):
    m=自我保护
    对于我的合作:
    m=m[i]
    返回m
    def setVal(自身、协调、val):
    m=自我保护
    
    #!/usr/bin/env python3
    
    import itertools
    import copy
    
    class Matrix:
      def __init__(self, dim):
        m=None
        for i in dim:
          m=[copy.deepcopy(m) for j in range(i)]
        self.mat=m
      def getVal(self, coord):
        m=self.mat
        for i in coord:
          m=m[i]
        return m
      def setVal(self, coord, val):
        m=self.mat
        l=coord.pop()
        for i in coord:
          m=m[i]
        coord.append(l)
        m[l]=val
    
    def sumOfNumbers(digits):
      def _sumOfNumbers(counts):
        max_v=-1
        for v in counts:
          if v<0:
            return (0,0)
          elif v>max_v:
            max_v=v
        if m.getVal(counts)==None:
          c=0
          s=0
          if max_v==0:
            c=1
          else:
            for i, d in enumerate(digits.keys()):
              counts[i]-=1
              r=_sumOfNumbers(counts)
              counts[i]+=1
              c+=r[0]
              s+=r[1]*10+r[0]*d
    
          m.setVal(counts, (c,s))
        return m.getVal(counts)
    
      dim=[v+1 for v in digits.values()]
      m=Matrix(dim)
      tot_val=0
      for i in itertools.product(*map(lambda x: range(x), dim)):
        r=_sumOfNumbers(list(i))
        tot_val+=r[1]
    
      return tot_val
    
    def main():
      x=1
      y=1
      z=1
      print(x,y,z)
      print(sumOfNumbers({4: x, 5: y, 6: z}))
    
    if __name__ == "__main__":
      main()
    
    4 + 5 + 6 + 40 + 50 + 50 + 60 + 40 + 60 + 400 + 400 
      + 500 + 500 + 600 + 600 = 3315
    
    int  q, a=0, b=0, c=0, x, y, z,  l, r,count=0;
    long long int  sum = 0,i,n,temp;
    cin >> x >> y>>z;
    string xyz = "4";
    for (i = 0; i>-1; i++)
    {
        n = i;
        //sum = 12345620223994828225;
        //cout << sum;
        while (n > 0)
        {
            temp = n % 10;
            if
                (temp == 4)
            {
                a++;
            }
            if (temp == 5)
            {
                b++;
            }
            if (temp == 6)
            {
                c++;
            }
            count++;
            n = n / 10;
    
        }
    
        if (a <= x && b <= y && c <= z && (a + b + c) == count)
        {
            temp = i%mod;
            sum = (sum + temp) % mod;
    
        }
        else if ((a + b + c) > (x + y + z))
            break;
        if (count == c)
        {
            i = 4 * pow(10, c);
        }
        count = 0;
        a = 0;
        b = 0;
        c = 0;
        temp = 0;
    }
    cout << sum+4;
    
    return 0;
    
    pow = (long) Math.pow(10,t - 1) / 9
    
    #include <bits/stdc++.h>
    #define ll int
    #define mod 1000000007
    using namespace std;
    struct p
    {
        ll f,s;
    }dp[102][102][102]={0};
    
    p c(ll x,ll y,ll z)
    {
        if (min(x,min(y,z)) < 0)
        {
            p temp;
            temp.f=temp.s=0;
            return temp;
        }
        if (!max(x,max(y,z)))
        {
            p temp;
            temp.f=1;
            temp.s=0;
            return temp;
        }
        if(dp[x][y][z].f&&dp[x][y][z].s) return dp[x][y][z];
        p ans;
        ans.f=ans.s=0;
        for (int i=4;i<7;i++)
        {
            p temp;
            if(i==4) temp=c(x-1, y, z);
            if(i==5) temp=c(x, y-1, z);
            if(i==6) temp=c(x, y, z-1);
            ans.f = (ans.f+temp.f)%mod;
            ans.s = ((long long)ans.s+((long long)i)*(long long)(temp.f) + 10*(long long)temp.s)%mod;
        }
        dp[x][y][z].f=ans.f;
        dp[x][y][z].s=ans.s;
      return ans;
    }
    
    int main()
    {
        ll x,y,z,ans=0;
        scanf("%d%d%d",&x,&y,&z);
        for (ll i = 0; i <= x; ++i)
        {
            for (ll j = 0; j <= y; ++j)
            {
                for (ll k = 0; k <= z; ++k)
                {
                   ans = (ans + c(i, j, k).s)%mod;
                   cout<<dp[i][j][k].f<<" "<<dp[i][j][k].s<<endl;
                }
            }
        }
        printf("%d",ans);
      return 0;
    }