阅读下面程序,请回答如下问题:
问题1:这个程序要找的是符合什么条件的数?
问题2:这样的数存在么?符合这一条件的最小的数是什么?
问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间精确到分钟(电脑:单核CPU 4.0G Hz,内存和硬盘等资源充足)。
问题4:在多核电脑上如何提高这一程序的运行效率?
(注:该程序、用C#语言编写,但是只要有C语言基础完全没有阅读压力,如果对部分语句不懂请自行查询)
要求:将上述问题结果写到博客上。
using System;
using System.Collections.Generic;
using System.Text;
namespace FindTheNumber
{
class Program
{
static void Main(string[] args)
{
int [] rg =
{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,30,31};
for (Int64 i = 1; i < Int64.MaxValue; i++)
{
int hit = 0;
int hit1 = -1;
int hit2 = -1;
for (int j = 0; (j < rg.Length) && (hit <=2) ; j++)
{
if ((i % rg[j]) != 0)
{
hit++;
if (hit == 1)
{
hit1 = j;
}
else if (hit == 2)
{
hit2 = j;
}
else
break;
}
}
if ((hit == 2)&& (hit1+1==hit2))
{
Console.WriteLine("found {0}", i);
}
}
}
}
我个人理解代码时是当有循环时逐步记录一下个变量的值,这样能更方便计算结果。
但是这个代码的循环次数有点多,这就要求我们通过几次的循环找到规律,然后再继续判断。
首先,第一次循环
i=1时,
{ j=0, rg[0]=2,hit=1,hit1=0,hit2=-1,此时还可以再循环
so j=1, rg[1]=3,hit=2,hit1=0,hit2=1, hit<=2 满足,还可以循环
j=2 , rg[2]=4,hit=3,hit1=0,hit2=1, 结束循环
但是在下方比较判断条件时时,hit!=2.
}
接下来继续外部大循环
i=2时,
{
j=0,rg[0]=2,hit=0,hit1=-1,hit2=-1
j=1,rg[1]=3,hit=1,hit1=1,hit2=-1
j=2,rg[2]=4,hit=2,hit1=1,hit2=2
j=3,rg[3]=5,hit=3,hit1=1,hit2=2 结束
可以看出判断条件 依然 hit!=2
}
当记录到这里就应该想想从判断条件入手想问题了,我们根据上方for (int j = 0; (j < rg.Length) && (hit <=2) ; j++)这句可以看出,循环结束的条件时读完数组或hit<=2, 而这句if ((hit == 2)&& (hit1+1==hit2)) 则是说明在上方数组的所有存有的数中找到两个连续的数,i 不能被 2~31 中相邻的这两个数整除,但可以被其余28个数整除。
答
1,这个程序是要在-263到263之间的整数找到一个数,不能被 2~31 中相邻的这两个数整除,但可以被其余28个数整除。
2,额 这个数我是真不知道,不过问了其他同学说是16,17与其它28个数的最小公倍数。是23*33*52*7*11*13*19*23*29*31=2123581660200
3,这个问题粗略的算需要计算外层的循环次数*循环一次的时间,2^63 = 9.2233720368548 * 10 18,
但是我并不知道循环一次所需的时间,百度一下说执行一亿次简单的循环对确定机器周期为12M晶振的计算机来说是1S,所以结果为90亿秒,9000000000/3600=2500000 days
4,我认为应该尽可能的关闭其他进程,保证该程序的正常运行吧。