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);

时间: 2024-11-06 12:27:41

2017-9-16C#笔记(枚举算法,百元买鸡)的相关文章

百元买鸡问题:用100元买100只鸡,其中母鸡每只3元,公鸡每只2元,小鸡1元,且每种鸡至少买1只。

#include<stdio.h>void main(){ int x,y,z; for(x=1;x<=32;x++) { for(y=1;y<=48;y++) { z=100-x-y; if((z%3==0)&&(3*x+2*y+z/3==100)) { printf("hen=%d,cock=%d,chicken=%d\n",x,y,z); goto laber; } } }laber:;} 原文地址:https://www.cnblogs.

基础算法题-----百元买百鸡

基础算法题-–百元买百鸡 题目:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱. 首先来分析一下: 设公鸡为x只,母鸡为y只,小鸡为z只,可的 x+y+z=100 5x+3y+z/3=100 由于每种鸡最少1只,所以公鸡最多能有(100 - 3 - 1) / 5只,母鸡最多能有(100 - 5 - 1) / 3只 至此我们便可以编码实现了 // 买公鸡最大数量 int gongJI = (10

SDUST 软件工程2016-作业4-A 百钱买鸡问题

解决百钱买鸡问题原本并不困难,关键的是这道题对其进行了升级,测试数据太大,传统的解法,像三重循环,二重循环都会导致超时. 这道题正确的解法应该是结合数学方程进行化简,将其转化为1层循环: x+y+z=n ax+by+c/d*z=m 由上述两个方程联立可用其他量表示出y来.从而只需要枚举x就能解决该题. 在求方程之后注意要化简,只有能整除的时候才进行整除.最后与m比较的时候因为c/d的问题,所以等式两边同时乘以d以消除误差. 最后千万不要加上z%d==0的条件,因为例如当3元买12小鸡的时候,实际

0002_百钱买鸡

百钱买鸡:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,用100文钱买100只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱? 思路:设定公鸡,母鸡,小鸡各买x,y,z只,则满足下列条件: x+y+z=100; 5x+3y+z/3=100: 1 __author__ = 'qq593' 2 # /usr/bin/python 3 # -*- coding:utf-8 -*- 4 5 #x is the unknown number 6 for y in ra

百文买鸡

1 /* 2 百文买鸡 3 公鸡5/只 母鸡3/只 小鸡3只/文 4 求百文百只里面的组合 5 */ 6 int main() 7 { 8 int cock, hen, chick; 9 for (cock = 0; cock < 100 / 5;cock++) 10 { 11 for (hen = 0; hen < 100 / 3;hen++) 12 { 13 chick = 100 - (cock + hen); 14 if ((cock * 5+hen*3+chick/3)==100)

算法之百元买百鸡

<算经> 书中提出的数学问题: 鸡翁一值钱五, 鸡母一值钱三, 鸡雏三值钱一. 百钱买百鸡, 问鸡翁.鸡母.鸡雏各几何? 1 /** 2 现在有100 元 , 买 100只鸡 3 公鸡 5 元每只 4 母鸡 3 元每只 5 小鸡 3只 1 元 6 x+y+z = 100 7 5*x+3*y+z/3=100 8 */ 9 10 11 12 #include<stdio.h> 13 14 void getResult(){ 15 int x,y,z; 16 for(int x=0;x&

Java基础------百元买百鸡问题

问题描述: 公鸡每只3元,母鸡每只5元,小鸡三只一元,问100元买100只鸡有几种买法? public static void main(String[] args) {           int count=0;     //用count纪录总方案数         //假设 i 表示买母鸡的个数,j 表示买公鸡的个数,k 表示买小鸡的个数        for(int i=0;i<=100/5;i++){                for(int j=0;j<=100/3;j++){

算法-百钱买白鸡

百钱买百鸡的问题算是一套非常经典的不定方程的问题,题目很简单:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱, 用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱. 分析:估计现在小学生都能手工推算这套题,只不过我们用计算机来推算,我们可以设公鸡为x,母鸡为y,小鸡为z,那么我们可以得出如下的不定方程 x+y+z=100, 5x+3y+z/3=100, 下面再看看x,y,z的取值范围,由于只有100文钱,则5x<100 => 0<x&l

百元买百鸡(C++实现)

#include<iostream> using namespace std; void main(void) { int a,b,c; //char DD,EE,FF; for (a=1;a<=20;a++) for (b=1;b<=33;b++) for (c=3;c<=99;c++) if (5*a+3*b+c/3==100) if (a+b+c==100) if (c%3==0) { //printf(a); std::cout<<"公鸡数为:&