首页 > C++ > (怀旧向)第六弹:算命预测

(怀旧向)第六弹:算命预测

2012年8月11日 发表评论 阅读评论

这个程序是一个很小的,很容易写的小程序,今天整理时无意中翻到,放上来看一下吧。

程序是这样的,不知道大家听过没,有些街边算命的,有一些人说可以猜出你姓什么,然后就给你看几张纸,每张纸上都写满了各种百家姓,然后你只要告诉他哪些纸上有哪些没有,然后他就可以马上“猜出”你姓什么。

我第一次接触到这个“魔术”是在小学看一本小学四年级的奥数书上,上面开始讲解进制的概念,然后出了道题,说老师让学生心里默想一个1~100的数,然后给他看若干张纸片,问他每张纸上有没有他内心想的那个数,然后老师就可以知道那个数是什么。题目让你讲解这个原理。(我一直觉得,这道题出现在小学四年级的奥数题里是不是太难了。。)

现在作为一个大学生,一个懂得何为二进制的大学生,这个手法显然是可以瞬间识破的(不过算命那个还要背一张比较大的数字→姓氏的表。。) 。

然后下面那个程序就是模拟这个猜数的过程的。一点都不难。

不过我现在仍然记得当时写这个程序时出现的唯一的一个麻烦,就是当时算log2n来计算需要多少张纸的时候,需要算出log2n取整,但是当n取8的时候,理论上应该是得到3,但是计算机算出来的是2.9999999...,然后取个整,变成2了,最后研究了一下,只好计算log2(n+1)来解决问题。。


Code:

#include<iostream .h>
#include<math .h>
#include<stdlib .h>
#include<iomanip .h>
#include<conio .h>
void main()
{
    char ch;
    int max,a=0;
begin:
    cout< <"Input the max number:";
    cin>>max;
    int paper,k,all=0;
    paper=log(max+1)/log(2);
    paper+=1;
    int *n;
    n=new int[max*paper];
    int r;
    int i,j,t;
    for(i=1;i< =max;i++)
    {
        t=i;k=pow(2,paper-1);
        for(j=paper*(i-1);j<paper*i;j++)
        {
            if(t>=k) {n[j]=1;t=t-k;k=k/2;}
            else {n[j]=0;k=k/2;}
        }
    }
    for(r=paper;r>0;r--)
    {
        cout< <"                             第"<<paper-r+1<<"张"<<endl;a=0;
        for(i=r-1;i<max*paper;i=i+paper)
        {
            if(n[i]==1)
            {
                cout<<setw(6)<<i/paper+1;a++;if(a%10==0) cout<<endl;
            }
        }
        cout<<endl<<endl;
        cout<<"有你心里想的那个数吗?(Y/N)"<<endl;
        ch=getche();
        while(ch!='n'&&ch!='y')
        {
            cout<<"input error";
            cin>>ch;
        }
        if(ch=='y')
            all=all+pow(2,paper-r);
        system("cls");
    }
    cout< <"你想的数是——————"<<all<<"  吗?"<<endl;
    getche();
    system("cls");
    delete []n;
    goto begin;
}

【完】

本文内容遵从CC版权协议,转载请注明出自http://www.kylen314.com

分类: C++ 标签: