| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2049 人关注过本帖
标题:求助:我用我的编译器做出来结果对,但是A不了,显示结果错误
只看楼主 加入收藏
yx1998
Rank: 2
等 级:论坛游民
威 望:1
帖 子:30
专家分:35
注 册:2015-7-24
收藏
得分:0 
图片附件: 游客没有浏览图片的权限,请 登录注册

静心学习,远离浮躁。
2015-07-26 21:18
ys344517874
Rank: 1
等 级:新手上路
帖 子:9
专家分:2
注 册:2015-7-26
收藏
得分:0 
回复 9楼 yx1998
就是在网上做的题呀   提交的时候不能被accept

+0.5那个是个坑哦   double 型的在机器里是近似数  强行int后可能会使值-1  +0.5保证四舍五入
2015-07-26 21:18
yx1998
Rank: 2
等 级:论坛游民
威 望:1
帖 子:30
专家分:35
注 册:2015-7-24
收藏
得分:0 
回复 7楼 ys344517874
原来是这样 涨姿势了 可是我运行真的是对的

静心学习,远离浮躁。
2015-07-26 21:19
ys344517874
Rank: 1
等 级:新手上路
帖 子:9
专家分:2
注 册:2015-7-26
收藏
得分:0 
回复 13楼 yx1998
我的也是对了  0到9999都测试过  可那网站就是不A我   所以来问问大家的看法
2015-07-26 21:22
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:336
专家分:1135
注 册:2014-4-13
收藏
得分:3 
此题如果把阶乘计算出来,再求非零值,理论上可以,实际很难完成,阶乘值太大了,应该找到一些算法,以下一些规律,有助于解决问题:去掉所有因数末尾的0对结果无影响,如12300变为123。如果把末尾为5的因数去掉,那么结果只与所有因数的个位有关。所有偶数都可化为2的n次方乘一个奇数。把阶乘的所有因数分3种情况处理:末位非5的奇数,偶数,末位为5的数。
以下是实现的代码供参考。
#include<stdio.h>
#include <stdlib.h>
int main()
{
   int notz( int );
    int n;
    scanf("%d",&n);
    printf("%d\n",notz(n));
    return 0;
}
int notz( int n)
{
     int i,k,w;
    unsigned int m,s;
   
    k=1;
    s=n;
    w=s%10;
    s/=10;
    while(s!=0)
     {
    for(i=0 ;i<s;i++) k=(9*k)%10;
    if(w>=3) k=(3*k)%10;
    if(w>=7) k=(7*k)%10;
    if(w>=9) k=(9*k)%10;
    w=s%10;
    s/=10;
      }
     if(w>=3) k=(3*k)%10;
     if(w>=7) k=(7*k)%10;
     if(w>=9) k=(9*k)%10;

    //获得因子2的个数,处理偶数
   
    m=0;
    for(i=0 ;i<n-10;i+=10)
   
     {
       w=i+2;
       while((w&1)==0){m++;w>>=1;}
       k=(k*w)%10;
        w=i+4;
       while((w&1)==0){m++;w>>=1;}
       k=(k*w)%10;
        w=i+6;
       while((w&1)==0){m++;w>>=1;}
       k=(k*w)%10;
        w=i+8;
       while((w&1)==0){m++;w>>=1;}
       k=(k*w)%10;
      }
   
      if(i+2<=n)
    {
       w=i+2;
       while((w&1)==0){m++;w>>=1;}
       k=(k*w)%10;
    }
       if(i+4<=n)
    {
        w=i+4;
       while((w&1)==0){m++;w>>=1;}
       k=(k*w)%10;
     }

        if(i+6<=n)
    {
      w=i+6;
       while((w&1)==0){m++;w>>=1;}
       k=(k*w)%10;
    }
        if(i+8<=n)
    {
     w=i+8;
       while((w&1)==0){m++;w>>=1;}
       k=(k*w)%10;
     }
     
        for(i=20;i<=n;i+=20)
        {
          s=i;
          while(s%10==0)s/=10;
        if((s&1)==0)
        {  
       while((s&1)==0){m++;s>>=1;}
       k=(k*s)%10;
          }
        }

   //处理末尾为5的数
    for(i=5;i<=n;i+=10)
    {
     s=i;
     while(s%5==0)
      {
        s=s<<1;//用偶数2去乘,直到末尾非5
    m--;
    while(s%10==0)s/=10;
       }
      k=(k*s)%10;
     }
   
     for(i=50;i<=n;i+=50)
      {
        s=i;
        while(s%10==0)s/=10;
        if(s%5==0)
           {
             while(s%5==0)
               {
                 s=s<<1;//用偶数2去乘,直到末尾非5
                m--;
             while(s%10==0)s/=10;
                }
                k=(k*s)%10;
      
             }
         }
    //处理剩余偶数

    for(i=m;i>0;i--) k=(k<<1)%10;

    return k;
  }

[ 本帖最后由 jklqwe111 于 2015-7-30 18:42 编辑 ]
2015-07-27 21:31
诸葛欧阳
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:流年
等 级:贵宾
威 望:82
帖 子:2790
专家分:14619
注 册:2014-10-16
收藏
得分:0 
以下是引用ys344517874在2015-7-26 21:06:05的发言:

时限是1000ms呀  应该不可能超时吧

对于较大的数它的阶乘非常大如果计算出来肯定会溢出

一片落叶掉进了回忆的流年。
2015-07-28 05:00
醒山
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:9
帖 子:463
专家分:2071
注 册:2015-5-25
收藏
得分:3 
int A( int n)这是什么?
2015-07-28 07:44
jklqwe111
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:35
帖 子:336
专家分:1135
注 册:2014-4-13
收藏
得分:0 
在阶乘中只有末位为5的数与偶数相乘才能产生0,设法把末位为5的数进行转化,使之末位不为5,这样连乘时每次只取1位就可以了,以下用筛选的方法进行实现。

#include<stdio.h>
#include <stdlib.h>
int main()
{
    int notz( int );
    int n;
    scanf("%d",&n);
    printf("%d\n",notz(n));
    return 0;
}
int notz( int n)
{
     int i,j,k,m ,s;
     int *data;
    data=(int*)malloc((n+1)*sizeof(int));
    for(i=2;i<=n;i++) data[i]=i;
   
    //同时把2和5的n次方的数置1
    i=5;
    j=2;
    while(i<=n)
    {
      data[i]=1;
      data[j]=1;
      i*=5;
      j*=2;  
    }
   
    //消去末尾的0,用2去乘末位为5的数,去除末尾的0,如末位仍为5,再用2去乘,记录所用2的个数
    m=0;
    for(i=10;i<=n;i+=10)
    {
      s=i/10;
      while(s%10==0) s/=10;//消去末尾的0
      data[i]=s;   
      while(s%5==0)
         {
           m++;
           s=s*2/10;
         }
      data[i]=s;
    }
   
    //处理末位为5的数
    for(i=5;i<=n;i+=10)
    {
      s=data[i];   
      while(s%5==0)
         {
           m++;
           s=(s<<1)/10;
         }
     data[i]=s;   
    }
   
    //除去偶数中m个2
    j=2;
    for(i=m;i>0;i--)
    {
      while((data[j]&1)!=0)j+=2;//找到偶数
      data[j]>>=1;   
    }
   
    //各数相乘,每次只取最后一位
    k=1;
    for(i=2;i<=n;i++) k=(k*data[i])%10;
    free(data);
    return k;
  }

[ 本帖最后由 jklqwe111 于 2015-7-29 17:09 编辑 ]
2015-07-29 16:55
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:3 
回复 18楼 jklqwe111
想法挺好的,就是代码有点儿绕。

程序代码:
unsigned foo( unsigned n )
{
    if( n <= 1 ) return 1;

    // n! 的因子中有a个5,b个2
    unsigned a=0, b=0;
    for( unsigned i=n; i!=0; i/=5 ) a += i/5;
    for( unsigned i=n; i!=0; i/=2 ) b += i/2;
    // n! 的因子中2的数目比5的数目多b-a个,设2的(b-a)次方的最后一位数为 s
    unsigned s = (1u<<((b-a-1)%4+1))%10;
    // 计算阶乘,但剔除因子2和因子5
    for( unsigned i=3; i!=n+1; ++i )
    {
        unsigned t = i;
        while( t%5 == 0 ) t/=5;
        while( t%2 == 0 ) t/=2;
        s = (t%10*s)%10;
    }
    return s;
}

to 题主:这道题其实很简单呀,因为有道类似的题目是“求n!尾部0的数目”,举一反三即可。
2015-07-30 09:28
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
如果ACM的,还可以作弊一下,因为题目中有一句“不大于4220”。
程序代码:
unsigned foo( unsigned n )
{
    if( n <= 1 ) return 1;

    for( unsigned i=n-1; i!=0; --i )
    {
        n = (n*i)%1000000; // 经过测试,4220! 的中间运算最多只涉及到后6位非零数。
        while( n%10 == 0 ) n/=10;
    }

    return n%10;
}


2015-07-30 09:43
快速回复:求助:我用我的编译器做出来结果对,但是A不了,显示结果错误
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029919 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved