百度首页 | 百度空间
 
查看文章
 
数字迷阵(zt)
2008-07-16 09:18

小可可参观科学博物馆时,看到一件藏品,上面有密密麻麻的数字,如下所示:
1 2 3 5 8 13 21 34 55 89 144 ...
4 7 11   18 29 47 76 123   199 322 521 ...
6 10   16   26 42 68 110   178   288 466 754 ...
9 15   24   39 63 102   165   267   432 699 1131 ...
12   20   32   52 84 136   220   356   576 932 1508 ...
14   23   37   60 97 157   254   411   665 1076   1741 ...
17   28   45   73 118   191   309   500   809 1309   2118 ...
19   31   50   81 131   212   343   555   898 1453   2351 ...
22   36   58   94 152   246   398   644   1042   1686   2728 ...
25   41   66   107   173   280   453   733   1186   1919   3105 ...
27   44   71   115   186   301   487   788   1275   2063   3338 ...
...
仔细一分析,发现还挺有规律。
原来,第一行是Fibonacci数列。即,该行中除了第一个和第二个数分别为1和2之外,其他数都是其左侧相邻的两个数之和。
其后各行也类似于Fibonacci数列。只是第i行的第一个数是前 行中未出现的最小正整数,而其第二个数与该行第一个数以及所在行的编号相关,即A[i,2]=A[i,1]*2-(i-1) 。如在第一行中未出现的最小正整数为4,前三行中未出现的最小正整数为9。故第二行以4和7开头,而第四行以9和15开头。
小可可高兴地把这个发现告诉了爷爷。爷爷问道:你能否一口报出第i行、第j列的那个数对m取模的结果是多少呢?
聪明的小可可通过心算就能知道答案。你是否能编写程序求解呢?

输入:每行有三个分别用一个空格隔开的正整数,分别是i、j和m。
其中,i, j<=1000000000 ,2<=m<=10000 。
输出:每行输出对应的第i行、第j列的那个正整数对m取模的结果。

样例:
(1) 输入(matrix.in):
1 2 99
输出(matrix.out):
2
(2) 输入(matrix.in):
9 1 999
输出(matrix.out):
22

原贴见:
http://bbs.chinaunix.net/viewthread.php?tid=1028591&extra=page%3D4%26amp%3Bfilter%3Dtype%26amp%3Btypeid%3D134

给出一个自己的程序,不过没找到什么规律,挺笨的!希望高手能给个更优的方法出来。
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<bitset>
#include<cstdlib>
using namespace std;
const unsigned long MAX=10000L;
int minIndex(const bitset<MAX>&b){
   static int index=0;
   if(index>MAX-1){
     cout<<index<<endl;
     throw "index overflow";
   }
   while(b[++index]);
   return index;
}
int main(int argc,char *argv[]){
  bitset<MAX>b;
  int rownum=0,colnum=0;
  cout<<"please input the row and col number:";
  cin>>rownum>>colnum;
  vector< vector<int> > matrix;
  int row=1;
  while(row<=rownum){
    vector<int> *v=new vector<int>(colnum);
    (*v)[0]=minIndex(b);
    (*v)[1]=(*v)[0]*2-(row-1);
      b[(*v)[0]]=1;
      b[(*v)[1]]=1;
    for(int i=2;i<colnum;i++){
      (*v)[i]=(*v)[i-1]+(*v)[i-2];
      if((*v)[i]<MAX) b[(*v)[i]]=1;
    }
    matrix.push_back(*v);delete v;
row++;
  }
  for(int i=0;i<matrix.size();i++){
    for(int j=0;j<matrix[i].size();j++){
      cout<<matrix[i][j]<<'\t';
    }
    cout<<endl;
  }
  cout<<"please input the i,j and m:";
  int i,j,m;
  cin>>i>>j>>m;
  if(i<0||i>=rownum||j<0||j>=colnum){
    cerr<<"range error"<<endl;
    exit(1);
  }
  cout<<"The result is:"<<matrix[i][j]%m<<endl;
  }

原文见:数字迷阵(zt)


类别:计算机 | 添加到搜藏 | 浏览() | 评论 (3)
 
最近读者:
 
网友评论:
1
2008-07-17 01:43
以下是我用C++写的,感觉对的,但运行出错,请改一改,谢谢!
#include<iostream>
using namespace std;
int main()
{
long i,j,m,k,a(0),p,q;
cin>>i>>j>>m;
long **A=new long *[i];
for(k=0;k<i;k++)
A[k]=new long [j];
A[0][0]=1;
A[0][1]=2;
if(i==1)
{
for(k=2;k<j;k++)
A[i-1][k]=A[i-1][k-1]+A[i-1][k-2];
}
else
{
k=4;
for(p=0;p<i-2;p++)
{
while(1)
{
a=0;
for(q=0;q<j;q++)
{
if(k!=A[p][q])
a++;
}
if(a!=j)
k++;
else
break;
}
}
A[i-1][0]=k;
A[i-1][1]=A[i-1][0]*2-i+1;
for(k=2;k<j;k++)
A[i-1][k]=A[i-1][k-1]+A[i-1][k-2];
}
cout<<A[i-1][j-1]%m<<endl;
for(k=0;k<i;k++)
delete []A[k];
delete []A;
return 0;
}
 
2
2008-07-17 09:02
感觉是程序中限定了生成的最大列数为J的原因。如果输入J为0(或者很小的数)的话,每一行的数列没有完全展开,可能会造成后续行中起始位置的错误。
 
4
2008-07-18 09:00
又是ACM的强人,班门弄斧了!
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码:
 

     

©2008 Baidu