2017-9-16C#笔记(枚举算法,百元买鸡)

  1. 枚举算法:

百元买鸡

枚举算法的Ì例子:问题如下:某3人有100元打算买100只鸡,其中公鸡为5元每只,母鸡为3元每只,小?鸡为3只1块钱,问可以买多少只公鸡,母鸡,小鸡?

            int x, y, z;

            for (x = 0; x <= 20; x++)

                for (y = 0; y <= 33; y++)

                    for (z = 0; z <= 100; z++)

                        if ((x + y + z == 100) && (5 * x + y * 3 + z / 3 == 100) && (z % 3 == 0))

                            Console.WriteLine("公鸡|:{0}只,母?鸡:{1}只,小鸡:{2}只", x, y, z);

上述运算执行的次数为21*34*101=71114

问题的优化思想如下:

问题中,由于三种鸡的和是固定的,因此只要枚举的两种鸡(x,y),第三种鸡就可以根据约定的条件求得(z=100-x-y),就这样就缩小了枚举的范围变成了双重循环。之所以选择Z,是因为Z的数值较大,优化的效果更好,此时的循环的次数就变成了:21*34=714。

int x, y, z;

            for (x = 0; x <= 20; x++)

                for (y = 0; y <= 33; y++)

               {

                      z=100-x-y;

              if ((x + y + z == 100) && (5 * x + y * 3 + z / 3 == 100) && (z % 3 == 0))

                            Console.WriteLine("公鸡|:{0}只,母?鸡:{1}只,小鸡:{2}只", x, y, z);

}

问题的再进一步的优化:

  如果从数学的角度来考虑枚举算法的进一步的优化,程序的效率就会进一步的优化

根据题意:约束条件为:5X+3Y+Z/3=100;X+Y+Z=100;约去一个Z则得到7X+9Y=100;X+Y+Z=100;所以只要枚举出X(最多位14)则Y,Z的值就可以自然而然的得到确定了。

计算1至N中数字X出现的次数,其中N〉=9,X为0-9

 

方法1:采用枚举的算法,分立出1-N范围内所有的数据的每一位上的数字,查看是否为X,然后计数。

int cnt = 0, i, k, n, x;

            n = Convert.ToInt32(Console.ReadLine());

            x = Convert.ToInt32(Console.ReadLine());

            for (i=1;i<=n;i++)

            {

                k=i;

                for (; k>0;k/=10)

                    if (k %10==x)

                        cnt++;

            }

            Console .WriteLine ("{0}",cnt);

这个方法的缺点就是时间复杂度太高,计算市一个数中X的出现的次数的时间复杂度为O(log10N),计算全部的数中X的时间复杂度为O(nlog10N)

算法的优化思维如下:

利用数学公式直接计算最终的结果,一次求出数字中X在个无人,视为百威的出现的是次数,在相加得到最终的结果。这里X的范围为1-9,因为=0不符合下列规律,需要单独的计算。

首先规律如下:

(1)   从1到10,在他们的个位数中任意的X都出现了1次

(2)   从1至100,在他们的十位数中,任意的X都出现了10次

(3)   从1至1000,在他们的百位数中,任意的X都出现了100次

以此类推,从1至10i,在他们的左数第二位(右数第i位)中,任意的X都出现了10i-1次。

计算右数第i位包含的X的个数算法:

(1)   取第i位左边(高位)的数字,乘以10i-1,得到基础值a。

(2)   取第i位数字,计算修正值:

如果大于X,则结果为a+10i-1

如果小于X,则结果为a。

如果等于X,则第i为右边(低位)数字,设为b,最后的结果为a+b+1。时间复杂度为

O(log10N)

代码如下:

   int cnt = 0, i, k, n, x, c;

            n = Convert.ToInt32(Console.ReadLine());

            x = Convert.ToInt32(Console.ReadLine());

            for (i = 1; (k = n / i) != 0; i*=10)

            {

                cnt += (k / 10) * i;

                c = k % 10;

                if (c> k)

                    cnt += i;

                else if (c == x)

                    cnt += n - k * i + 1;

            }

            Console.WriteLine("{0}", cnt);

 

posted @ 2017-09-24 08:54  Adaisme  Views(598)  Comments(0Edit  收藏  举报