#include<stdio.h>
int f[15];
bool jos(int ,int );
int main()
{
 
int i,j,k,m,n;
 
for(i=1;i<14;i++)
  
for(j=i;;j++)
   
if(jos(i,j))
   {
    f[i]
=j;
    
break;
   }
 
while(scanf("%d",&n),n)
  printf(
"%d\n",f[n]);
 
return 0;
}
bool jos(int n,int m)//n代表每一边的人数,m代表所报的数
{
 
int start=0,end=n-1,killed;
 
int i,j;
 
bool flag=true;
 
for(i=2*n;i>n;i--)//从头进行模拟
 {
  killed
=(m-1)%i;//i代表剩余的人数
  if((killed<=end)&&(killed>=start))
  {
   flag
=false;
   
break;
  }
  start
=((start-m)%i+i)%i;//按照那个编号变化公式重新进行赋值
  end=((end-m)%i+i)%i;//加上i,再%i的目的是保证它非零
 }
 
return flag;
}
posted @ 2011-05-08 14:56 新伟 阅读(206) 评论(0) 编辑
先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);
假设给出一个数10234432,那么log10(10234432)=log10(1.0234432*10^7)=log10(1.0234432)+7;

log10(1.0234432)就是log10(10234432)的小数部分.

log10(1.0234432)=0.010063744
10^0.010063744=1.023443198
那么要取几位就很明显了吧~
先取对数(对10取),然后得到结果的小数部分bit,pow(10.0,bit)以后如果答案还是<1000那么就一直乘10。
注意偶先处理了0~20项是为了方便处理~

这题要利用到数列的公式:an=(1/√5) * [((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....)
取完对数
log10(an)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0)+log10(1-((1-√5)/(1+√5))^n)其中f=(sqrt(5.0)+1.0)/2.0;
log10(1-((1-√5)/(1+√5))^n)->0
所以可以写成
log10(an)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0);
最后取其小数部分。
  1. #include<iostream>
  2. #include<cmath>
  3. using namespace std;
  4. int fac[21]={0,1,1};
  5. const double f=(sqrt(5.0)+1.0)/2.0;
  6. int main()
  7. {
  8.     double bit;
  9.     int n,i;
  10.     for(i=3;i<=20;i++)fac[i]=fac[i-1]+fac[i-2];//求前20项
  11.     while(cin>>n)
  12.     {
  13.         if(n<=20)
  14.         {
  15.             cout<<fac[n]<<endl;
  16.             continue;
  17.         }
  18.         bit=-0.5*log(5.0)/log(10.0)+((double)n)*log(f)/log(10.0);//忽略最后一项无穷小
  19.         bit=bit-floor(bit);
  20.         bit=pow(10.0,bit);
  21.         while(bit<1000)bit=bit*10.0;
  22.         printf("%d\n",(int)bit);
  23.     }
  24.     return 0;
  25. }
posted @ 2011-05-08 14:26 新伟 阅读(52) 评论(0) 编辑

给大家提供一个资料

http://zhidao.baidu.com/question/15843599.html

 众所周知,有限小数是十进分数的另一种表现形式,因此,任何一个有限小数都可以直接写成十分之几、百分之几、千分之几……的数。那么无限小数能否化成分数? 

首先我们要明确,无限小数可按照小数部分是否循环分成两类:无限循环小数和无限不循环小数。无限不循环小数不能化分数,这在中学将会得到详尽的解释;无限循环小数是可以化成分数的。那么,无限循环小数又是如何化分数的呢?由于它的小数部分位数是无限的,显然不可能写成十分之几、百分之几、千分之几……的数。其实,循环小数化分数难就难在无限的小数位数。所以我就从这里入手,想办法“剪掉”无限循环小数的“大尾巴”。策略就是用扩倍的方法,把无限循环小数扩大十倍、一百倍或一千倍……使扩大后的无限循环小数与原无限循环小数的“大尾巴”完全相同,然后这两个数相减,“大尾巴”不就剪掉了吗!我们来看两个例子:

⑴    把0.4747……和0.33……化成分数。

想1:        0.4747……×100=47.4747……   

0.4747……×100-0.4747……=47.4747……-0.4747……

(100-1)×0.4747……=47

即99×0.4747…… =47 

那么  0.4747……=47/99



想2: 0.33……×10=3.33……

0.33……×10-0.33……=3.33…-0.33……

(10-1) ×0.33……=3

即9×0.33……=3

那么0.33……=3/9=1/3

由此可见, 纯循环小数化分数,它的小数部分可以写成这样的分数:纯循环小数的循环节最少位数是几,分母就是由几个9组成的数;分子是纯循环小数中一个循环节组成的数。

⑵把0.4777……和0.325656……化成分数。

想1:0.4777……×10=4.777……①

0.4777……×100=47.77……②

用②-①即得: 

0.4777……×90=47-4

所以, 0.4777……=43/90



想2:0.325656……×100=32.5656……①

0.325656……×10000=3256.56……②

用②-①即得: 

0.325656……×9900=3256.5656……-32.5656……

0.325656……×9900=3256-32

所以, 0.325656……=3224/9900

将纯循环小数改写成分数,分子是一个循环节的数字组成的数;分母各位数字都是9,9的个数与循环节中的数字的个数相同.

  将混循环小数改写成分数,分子是不循环部分与第一个循环节连成的数字组成的数,减去不循环部分数字组成的数之差;分母的头几位数字是9,末几位数字是0,9的个数跟循环节的数位相同,0的个数跟不循环部分的数位相同.

这代码比我的好多了,,,,太精典了。哎呀………………我为什么就写不出来这么简短的代码了

#include <iostream>
using namespace std;
int f(int u,int v)
{
    
while(u%v)
    {
      
int w=u%v;
      u
=v;
      v
=w;
    }
    
return v;
}
int main()
{
    
int t;
    
while(cin>>t)
    {
        
while(t--)
        {
            
char a[15];
            cin
>>a;
            
int p=0,q=0,t=0,x=0,y,k=1,l=1,max;
            
for(int i=2;a[i]!='\0';i++)
            {
                
if(!&& a[i]!='(') {p++;x*=10;x+=a[i]-'0';}
                
if(t && a[i]!=')') {q++;y*=10;y+=a[i]-'0';}
                
if(a[i]=='(') {t=1;y=x;q=p;}
            }
            
if(!q)
            {
                
while(p--)
                    k
*=10;
                max
=f(x,k);
                x
/=max;
                k
/=max;
                cout
<<x<<'/'<<k<<endl;
            }
            
else
            {
                
int m=y-x;
                
while(p--)
                    k
*=10;
                
while(q--)
                    l
*=10;
                
int n=l-k;
                max
=f(m,n);
                m
/=max;
                n
/=max;
                cout
<<m<<'/'<<n<<endl;
            }
        }
    }
    
return 0;
}
希望下个step不是数论了。。

posted @ 2011-05-08 13:41 新伟 阅读(19) 评论(0) 编辑

我和这题有缘吗?

知道三个点了 就可以求出直线和抛物线的方程 
然后就是非常简单的二重积分求面积 ^_^  

用抛物线的顶点公式y=a(x-x1)^2+y1外加另一个点x2算出a,然后对抛物线公式求积分,用积分的公式算出抛物线和x轴的面积,减去梯形的面积就行。

 

#include "stdio.h" 
int main() 

 
int n,i; 
 
double e,f,g,h,l,r,a,b,c,k,m,area; 
 scanf(
"%d",&n); 
 
for(i=0;i<n;i++
 { 
  scanf(
"%lf %lf",&e,&f);
  scanf(
"%lf %lf",&g,&h); 
  scanf(
"%lf %lf",&l,&r); 

  a
=(h-f)/((e-g)*(e-g));
  b
=-2*e*(h-f)/((e-g)*(e-g));
  c
=f-e*e*(h-f)/((e-g)*(e-g))+e*2*e*(h-f)/((e-g)*(e-g));
  k
=(h-r)/(g-l);
  m
=h-g*(h-r)/(g-l);
  area
=a*l*l*l/3+(b-k)*l*l/2+(c-m)*l-a*g*g*g/3-(b-k)*g*g/2-(c-m)*g; 
  printf(
"%.2f\n",area); 
 } 
 
return 0
}

 

 

posted @ 2011-05-08 13:36 新伟 阅读(15) 评论(0) 编辑

这个题目的思路,是这样的我们假设数字A是这样的一个数字 a*(10^(k+1)) + b*(10^k) + c 其中 a 为任意数字,b为去掉的那一位数字,范围 [0,9] 的整数,c<10^k 。则去掉b后的数字B为 a*(10^k) + c ,而A+B的值可以用一下式子表示 (11*a+b)*(10^k) + 2*c 这个值等于 n , 我们枚举 k的值,从0到10 ,对于取定的k值,显然有一下对应 2*c = n%(10^k) 或者 2*c = n%(10^k) + 10^k ; 可以求出整数c的值,然后枚举 b的值,来确定a的值,使得a的值为整数 /..计算中可能会出现重复的结果,输出是记得要处理一下哦

 

#include<iostream>
#include
<algorithm>
using namespace std;
int re[100];
int main()
{
    
int n,a,i,j,k,num,x,y,temp,tt;

    
while(scanf("%d",&n) &&n)
    {
        num 
= 0,tt = 1;
        
for(k =0; k <= 10; k ++){
            
for(j = 0; j < 2; j ++){
                y 
= n% tt,x = n/tt;
                
if(j == 1)
                    y 
+= tt,x --;
                
if(x > 0 && y % 2 == 0){
                    
for(i = 0; i <= 9; i ++){
                        
if((x-i)%11 == 0){
                            a 
= (x-i)/11;
                            temp 
= tt*(a*10 +i) + y/2;
                            re[num
++= temp;    }}}}
            tt 
*= 10;
        }
        sort(re,re
+num);
        
if(num == 0)    printf("No solution.\n");
        
else{
            printf(
"%d",re[0]);
            
for(i =1; i < num; i ++)
                
if(re[i] != re[i-1])    printf(" %d",re[i]);
            printf(
"\n");
        }
    }
    
return 0;
}

 

posted @ 2011-05-08 13:31 新伟 阅读(129) 评论(0) 编辑
题目的大意是将一个数分解成素数的乘积。求最大的那个素数在素数表中的位置。与

FZU.1012(http://acm.fzu.edu.cn/problem.php?pid=1012)这一题分解素数的方法与原理相似。用prime[i]来存放i这个数字分解后最大素数的位置。2是素数,所以prime[2]=1;再先将所有2的倍数的prime[]都更新为1.即prime(4,6,8,10)都为1.又因为6又是3的倍数,3是更大的素数,所以将prime[6]更新为3.依此类推……

 1 #include<stdio.h>
 2 #define N 1000001
 3 int prime[N];
 4 int main()
 5 {
 6     for(int j=0;j<N;j++)
 7         prime[j]=-1;
 8     int num=0;
 9     for(int i=2; i<N; i++)
10     {
11         if(prime[i]==-1)
12         {
13             num++;
14             for(int j=i;j<N;j+=i) 
15                 prime[j]=num;
16         }
17     }
18     
19       int n;   
20       while(scanf("%d",&n)!=EOF)
21       { 
22           if(n==1)
23           printf("0\n");
24           else 
25           printf("%d\n",prime[n]);
26       } 
27   return 0;
28 }


posted @ 2011-05-08 12:52 新伟 阅读(46) 评论(0) 编辑

数学太差,转的。。

 

题目意思很清楚,不用多说,公式是 p+q-gcd(p,q)

举个例子:4 6,用一个矩形来切割,如下图

 

 





蓝色点线表示4等分线 红色实线表示6等分线,让蛋糕(矩形)可以平分为4份需要(4刀)和6份需要(6刀),总共需要10刀,但因为其中有两条线是重合的,没有必要切两次,所以应该减掉这两刀,就只剩下

10-2=8刀了。对于任何p和q,他们重合的线的数量就是他们的GCD,所以就~~~~

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int gcd(int a, int b) {
 6     return b ? gcd(b, a%b) : a;
 7 }
 8 int main() {
 9     int p, q;
10     while(scanf("%d%d"&p, &q) != EOF) {
11         cout << p + q - gcd(p, q) << endl;
12     }
13     return 0;
14 }

博客园以后贴代码默认语言改成c++好不好~

 

posted @ 2011-05-08 10:43 新伟 阅读(112) 评论(0) 编辑

http://acm.hdu.edu.cn/showproblem.php?pid=1713

输入 a/b c/d
转换后变成:
(a*d)/(b*d) 和 (c*b)/(b*d)
按照题意,就是在转相同的圈子(b*d圈)时,各自需要时间a*d和c*b.
所以,这里把a*b与c*b的最小公倍数求出来就可以了。
这样。求出的最小公倍数lcm再除以(b*d)就是所求的周期。
(http://www.wutianqi.com/)
但是,这里要求若无法整出,则写出分数形式,这时,
就可以求lcm与(b*d)的最大公约数gcd,
求出gcd后与(b*d)比较,若相等,则证明可以整除~~~~

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5  
 6 __int64 gcd(__int64 a, __int64 b)
 7 {
 8     if(a<b)
 9     {
10         a ^= b;
11         b ^= a;
12         a ^= b;
13     }
14     if(b == 0)
15         return a;
16     return gcd(b, a%b);
17 }
18  
19 __int64 lcm(__int64 a, __int64 b)
20 {
21     return a/gcd(a, b)*b;
22 }
23  
24 int main()
25 {
26     //freopen("input.txt", "r", stdin);
27     int nCases;
28     scanf("%d"&nCases);
29     for(int i=0; i<nCases; ++i)
30     {
31         char tmp;
32         __int64 a, b, c, d;
33         scanf("%I64d/%I64d %I64d/%I64d"&a, &b, &c, &d);
34         __int64 m=a*d, n=b*c, p=b*d;
35         __int64 k=lcm(m, n);
36         int h = gcd(k, p);
37         if(p==h)
38             printf("%I64d\n", k/h);
39         else
40             printf("%I64d/%I64d\n", k/h, p/h);
41     }
42     return 0;
43 }
posted @ 2011-05-08 10:15 新伟 阅读(255) 评论(2) 编辑