(1.1.8)循环算法的特征以及典型循环算法杨辉三角、螺旋队列等
2015-03-10 21:55
169 查看
循环算法的特征:
1)基于一定的数学规律
2)总能找到对应的基准点,并依据基准点展开算法
2、奇数(圈数,或X轴正坐标)平方规律(紫线)
观察这些基准值与max值之间关系,不难发现,这些基准值与max之间的差分别是1C(上边),3C(左边),5C(下边),7C(右边)(C表示当前圈数),在上边和下边,y坐标表示(或等于)圈数(即C=y),而在左边和右边,x坐标表示(或等于)圈数(即C=x)。因此前面提到的差值又可用坐标表示成1y,3x,5y,7x。因此就产生了各边基准值的计算公式:
topBase=max+y
leftBase=max+3x
bottomBase=max-5y
rightBase=max-7x
[java] view
plaincopy
/**
* 打印螺旋数列
*
* @author nathan
*
*/
public class SpiralSeq {
public static void main(String[] args) {
for (int y = -5; y <= 5; ++y) {
for (int x = -5; x <= 5; ++x) {
System.out.printf("%5d", spiral(x, y));
}
System.out.println();
}
}
private static Object spiral(int x, int y) {
int c = max(abs(x), abs(y));// 当前坐标所在圈
int max = (c * 2 + 1) * (c * 2 + 1);// 当前圈上最大值
if (y == -c) { // 上边
return max + (x + y);
} else if (x == -c) {// 左边
return max + (3 * x - y);
} else if (y == c) {// 下边
return max + (-x - 5 * y);
} else {// 右边
return max + (-7 * x + y);
}
}
private static int max(int n1, int n2) {
return n1 > n2 ? n1 : n2;
}
private static int abs(int x) {
return x > 0 ? x : -x;
}
}
(2)杨辉三角
Please write out the program output.(写出下面程序的运行结果。)【德国某著名软件咨询企业2005年10月面试题】
[cpp] view
plaincopy
// P92_example1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
#define LOOP 1000
int _tmain(int argc, _TCHAR* argv[])
{
int rgnC = 0;
for(int i = 0; i < LOOP; i++)
{
int x = rand();
int y = rand();
if(x*x + y*y < RAND_MAX*RAND_MAX)
rgnC++;
}
printf("%d\n", rgnC);
return 0;
}
解析:
这是我们见过的概率面试题中出得非常好的一道。
从表面上看,你完全无法看出它是一个概率问题。这里暗含的思想是一个1/4圆和一个正方形比较大小的问题,如图所示。
RAND_MAX是随机数中的最大值,也就是相当于最大半径R。x和y是横、纵坐标的两点,它们的平方和开根号就是原点到该点(x,y)的距离,当然这个距离有可能大于R,如b点,还有可能小于R,如a点。整个题目就蜕化成这样一个问题:随机在正方形里落1000个点,落在半径里面的点有多少个。如果落在里面一个点,则累计一次。
那这个问题就很好解决了,求落点可能性之比,就是求一个1/4圆面积和一个正方形面积之比。
1/4圆面积 = (1/4)x π x r x r
正方形的面积 = r x r
两者之比 = π/4
落点数 = π/4 x 1000 = 250 x π ≈ 785
答案:
出题者的意思显然就是要求你得出一个大概值,也就是250*π就可以了。实际上呢,你只要回答700~800之间都是正确的。
我们算的是落点值,落点越多,越接近250*π,落10个点、100个点都是很不准确的,所以该题落了1000个点。读者可以上机验证该程序,将LOOP改成10000、100000来实验,会发现结果越来越接近250*π。
1)基于一定的数学规律
2)总能找到对应的基准点,并依据基准点展开算法
(1)螺旋队列
螺旋队列的样子如下图:
两大规律:
1、螺旋规律2、奇数(圈数,或X轴正坐标)平方规律(紫线)
观察这些基准值与max值之间关系,不难发现,这些基准值与max之间的差分别是1C(上边),3C(左边),5C(下边),7C(右边)(C表示当前圈数),在上边和下边,y坐标表示(或等于)圈数(即C=y),而在左边和右边,x坐标表示(或等于)圈数(即C=x)。因此前面提到的差值又可用坐标表示成1y,3x,5y,7x。因此就产生了各边基准值的计算公式:
topBase=max+y
leftBase=max+3x
bottomBase=max-5y
rightBase=max-7x
[java] view
plaincopy
/**
* 打印螺旋数列
*
* @author nathan
*
*/
public class SpiralSeq {
public static void main(String[] args) {
for (int y = -5; y <= 5; ++y) {
for (int x = -5; x <= 5; ++x) {
System.out.printf("%5d", spiral(x, y));
}
System.out.println();
}
}
private static Object spiral(int x, int y) {
int c = max(abs(x), abs(y));// 当前坐标所在圈
int max = (c * 2 + 1) * (c * 2 + 1);// 当前圈上最大值
if (y == -c) { // 上边
return max + (x + y);
} else if (x == -c) {// 左边
return max + (3 * x - y);
} else if (y == c) {// 下边
return max + (-x - 5 * y);
} else {// 右边
return max + (-7 * x + y);
}
}
private static int max(int n1, int n2) {
return n1 > n2 ? n1 : n2;
}
private static int abs(int x) {
return x > 0 ? x : -x;
}
}
(2)杨辉三角
#include <stdio.h> main() { int i,j,n=0,a[17]={0,1},l,r; while(n<1 || n>16) { printf("请输入杨辉三角形的行数:"); scanf("%d",&n); } for(i=1;i<=n;i++) { l=0; for(j=1;j<=i;j++) { r=a[j]; a[j]=l+r; //每个数是上面两数之和 l=r; printf("%5d",a[j]); //输出杨辉三角 } printf("\n"); } }
(3)判断素数
一个大于1的自然数,除了1和它本身外,不能整除以其他自然数(质数),换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数。int judge(int a){ int j; for(j=2;j<=sqrt(a);j++){ if(a%j==0) return 1; } return 0; }
(4)概率题
题:Please write out the program output.(写出下面程序的运行结果。)【德国某著名软件咨询企业2005年10月面试题】
[cpp] view
plaincopy
// P92_example1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
#define LOOP 1000
int _tmain(int argc, _TCHAR* argv[])
{
int rgnC = 0;
for(int i = 0; i < LOOP; i++)
{
int x = rand();
int y = rand();
if(x*x + y*y < RAND_MAX*RAND_MAX)
rgnC++;
}
printf("%d\n", rgnC);
return 0;
}
解析:
这是我们见过的概率面试题中出得非常好的一道。
从表面上看,你完全无法看出它是一个概率问题。这里暗含的思想是一个1/4圆和一个正方形比较大小的问题,如图所示。
RAND_MAX是随机数中的最大值,也就是相当于最大半径R。x和y是横、纵坐标的两点,它们的平方和开根号就是原点到该点(x,y)的距离,当然这个距离有可能大于R,如b点,还有可能小于R,如a点。整个题目就蜕化成这样一个问题:随机在正方形里落1000个点,落在半径里面的点有多少个。如果落在里面一个点,则累计一次。
那这个问题就很好解决了,求落点可能性之比,就是求一个1/4圆面积和一个正方形面积之比。
1/4圆面积 = (1/4)x π x r x r
正方形的面积 = r x r
两者之比 = π/4
落点数 = π/4 x 1000 = 250 x π ≈ 785
答案:
出题者的意思显然就是要求你得出一个大概值,也就是250*π就可以了。实际上呢,你只要回答700~800之间都是正确的。
我们算的是落点值,落点越多,越接近250*π,落10个点、100个点都是很不准确的,所以该题落了1000个点。读者可以上机验证该程序,将LOOP改成10000、100000来实验,会发现结果越来越接近250*π。
相关文章推荐