回 帖 发 新 帖 刷新版面

主题:发小学题挑战高手

印度国王的棋盘           (30分)
[问题描述]:这是一个有名的古代故事。有一个数学家发明了一种棋盘献给了印度
            国王,数学家看国王非常欢喜,就向国王提出了奖赏的要求:在棋盘
            的第一格放一粒米,第二格放二粒米,第三格放四粒米,第四格放八
            粒米,.....也就是说每一格都放进了比前一格多一倍的米。国王认为
            这简直不值一提,就毫不犹豫的答应了。谁知结果却让国王大吃一惊,
            当放到第64格时,就已经一共用了18446744073709551615粒米。这
            在当时要几百年才能种出来。
                现假定该棋盘共有200格,请你编程计算从第N格至第M 格共有
            多少粒米,并以三位一撇的形式输出。

[输入]: 键盘输入整数N,M(1≤N,M≤200不用判错)。

[输出]: 精确输出从第N格至第M 格共有多少粒米,并以三位一撇的形式输出。

[样例]:输入:N,M=20,37
      
       输出:137,438,429,184



算24                (30分)
[问题描述]
给出4个1到1000之间的整数,用这4个整数,通过+、–、*的运算而得到24,运算规则如下:
1.    每个数必须使用一次,只能使用一次
2.    运算符无优先级之分,自左向右计算。

例如:输入4个数为2,9,3,1,
      则计算方法为3+9*2*1=24

[输   入]: 4个1到1000之间的整数

[输   出]: 若4个数不能产生出24,则输出error;
           若能产生,则输出产生式(若有多个,仅能输出一个)。

例如:输入:1,1,2,2              输入:4,4,4,4
      输出:error                    输出:4*4+4+4=24
          

回复列表 (共11个回复)

沙发

1、用高精度直接模拟
2、直接枚举
it's easy

板凳

有程序吗?

3 楼

第一题非常简单,直接用int64计算就可以了。
(1<<M) - (1<<(N-1))

4 楼

//第一题,没来得及加注释,效率也很低,大家不要见笑
#include<iostream.h>

#define N 100

void format(int a[]){
    int b=N-a[0];
    for(int i=N-1;i>=b;i--){
        if(a[i]>=10){
            a[i]=a[i]%10;
            a[i-1]++;
            if(i==b){
                a[0]++;
            }
        }
    }
}

void dnum(int a[]){
    int i=1;
    while(a[i]==0){
        if(a[i]==0)
            i++;
        else
            break;
    }
    a[0]=N-i;
}

void minus(int a[],int b[]){
    for(int i=N-1;i>=N-a[0];i--){
        if(a[i]>=b[i])
            a[i]-=b[i];
        else{
            a[i]=a[i]+10-b[i];
            a[i-1]--;
        }
    }
    dnum(a);
}

void main(){
    int n,m,num1[N],i,num2[N],j;
    cout<<"M:";
    cin>>m;
    cout<<"N(N<=M):";
    cin>>n;
    for(i=1;i<N;i++){
        num2[i]=0;
        num1[i]=0;
    }
    num1[N-1]=1;num1[0]=1;
    num2[N-1]=1;num2[0]=1;
    for(j=1;j<=m;j++){
        for(i=N-1;i>=N-num1[0];i--)
            num1[i]*=2;
        format(num1);
        dnum(num1);
    }
    for(j=1;j<=n;j++){
        for(i=N-1;i>=N-num2[0];i--)
            num2[i]*=2;
        format(num2);
        dnum(num2);
    }
    minus(num1,num2);
    cout<<endl;

    for(i=N-num1[0];i<=N-1;i++){
             cout<<num1[i];
    }
}
    

5 楼

能用PASCAL写吗?C我没学过[em8]

6 楼

int64,这就是用c的好处,pascal只能用高精

7 楼

这是高精的源代码,其余自己改把:
  var
  s1,s2:string;
  a,b:array[1..255] of integer;
  c:array[1..510] of integer;  {数组C用来存放结果,最大510位,为什么?}
  i,j,l,m,k1,k2,x,y,z,w:integer;
begin
  readln(s1); readln(s2); k1:=0;
  l:=length(s1); m:=length(s2);  {得到两个字符串的长度}
  for i:=l downto 1 do  {S1转换过程,把低位放在A[1]中}
     begin
         k1:=k1+1;
         a[k1]:=ord(s1[i])-48;       
     end;
  k2:=0;
  for i:=m downto 1 do   {S2转换过程,把低位放在B[1]中}
     begin
         k2:=k2+1;
         b[k2]:=ord(s2[i])-48;        
     end;
  for i:=1 to k1 do   {开始计算,从低位开始乘}
    for j:=1 to k2 do
       begin
         x:=a[i]*b[j];
         y:=x div 10;
         z:=x mod 10;
         w:=i+j-1;
         c[w]:=c[w]+z;
         c[w+1]:=c[w+1]+y+c[w] div 10;
         c[w]:=c[w]mod 10
       end;
  w:=k1+k2;
  if c[w]=0 then w:=w-1;  {判断最高位是否有数}
  for i:=w downto 1 do write(c[i]); {输出的时候注意顺序}
    writeln
end.

8 楼

int64 C++可以用吗???
再说了 2的200次方用int64 也是完全不够的呀?!~~

9 楼

对于非常非常巨大的数字(比如300--500位的数字)可以使用数组来表示。数组的每一个元素代表一位数字。当然加减乘除四则运算需要我们仔细编写函数实现了。
这样我们可以,用普通计算机表示极大长度的数字,并进行运算了。

10 楼

排列组合不是更简单吗?

我来回复

您尚未登录,请登录后再回复。点此登录或注册