算法竞赛入门经典(第二章)

2-1:位数
输入一个不超过10^9 的正整数,输出他的位数。例如12735的位数是5。请不要使用任何数学函数,只用四则因算和循环语句实现。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int main()
{
  int a,n=0;
  scanf("%d",&a);
  while(a!=0)
  {
    a/=10;
    n++;
  }
  printf("%d",n);
  return 0;
}

2-2:水仙花数
输出100~999中的所有水仙花数。若三位数ABC满足ABC=A^3+B^3+C^3,则称其为水仙花数。例如 153=1^3+5^3+3^3;所以153是水仙花数;

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int main()
{
  for(int i=1;i<=9;i++)
    for(int j=0;j<=9;j++)
      for(int k=0;k<=9;k++)
      {
        if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
          printf("%d%d%d\n",i,j,k);
      }
  return 0;
}

下题为转载!!

2-3:韩信点兵
相传韩信才智过人,从不直接清点自己的军队人数,只要让士兵先后以三人一排,五人一排,七人一排地变换队形,而他每次只掠一眼队伍的排位就知道总人数了。输入三个非负整数a,b,c,表示每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100;
样例输入:2 1 6
样例输出:41
样例输入:2 1 3
样例输出:No answer

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int main()
{
  int a,b,c;
  int ans;
  while(scanf("%d%d%d",&a,&b,&c)!=EOF)
  {
    ans=(70*a+21*b+15*c)%105;
    if(ans<10||ans>100)
      printf("No answer\n");
    else
      printf("%d\n",ans);
  }

  return 0;
}
 **原理**:

1.因为这个数能被5和7整除而不能被3整除,所以肯定是5和7的倍数,也就是35k,
但是我们需要保证被3除的结果是a,所以我们令k=2,这样,70k%3=1,而k=1时,35k%3=2,所以,能被5和7整除不能被3 整除且余数为a的数为70a。
2.被3和7整除,不能被5整除,则为21k,k=1时,正好余1,所以这个数为21b。
3.被3和5整除,不能被7整除,则为15k,k=1时,正好余1,所以这个数为15c。
所以,这个数为70a+21b+15c,又因为3、5、7的最小公倍数为105,
所以这个数肯定在0到105以内,所以对结果取余一下即可。
推广到其他情况也是同样道理。
比如,求除以5、7、11以后所得余数为a,b,c.则这个数是:231a+330b+210c,然后对5×7×11=385取余即可。

2-4:倒三角形
输入正整数n<=20,输出一个n层的倒三角形。例如n=5时输出如下:
#########
#######
#####
###
#
这是个倒三角形!!锥形的那种!

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int main()
{
  int n;
  scanf("%d",&n);
  for(int i=n;i>0;i--)
  {
    for(int j=1;j<=n-i;j++)
      printf(" ");
    for(int k=1;k<=2*i-1;k++)
      printf("#");
    printf("\n");
  }
  return 0;
}

2-5:统计
输入一个正整数n,然后读取n个正整数a1,a2….an,最后再读一个正整数m。统计a1,a2….an,中有多少个整数的值小于m。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define maxn 10000

int a[maxn];
int main()
{
  int n,m,countt=0;
  scanf("%d",&n);
  for(int i=0;i<n;i++)
    scanf("%d",&a[i]);
  scanf("%d",&m);
  for(int i=0;i<n;i++)
  {
    if(a[i]<m)
      countt++;
  }
  printf("%d\n",countt);
}

2-6:调和级数
输入正整数n,输出H(n)=1+1/2+1/3+…+1/n的值,保留三位小数。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define maxn 10000

int a[maxn];
int main()
{
  int n;
  double sum=0;
  scanf("%d",&n);
  for(int i=1;i<=n;i++)
    sum+=1.0/i;
  printf("%.3lf\n",sum);
  return 0;

}

2-7:近似计算
计算pi/4=1-1/3+1/5-1/7+……,直到最后一项小于10^-6。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define maxn 10000

int main()
{
  double sum=0,flag=1.0;
  int i=1;
  for(int i=1;;i=i+2)
  {
    double m=1.0/i*flag;
    flag/=-1;
    sum+=m;
    if(m<pow(10,-6))
      break;
  }
  printf("%lf\n",sum);
  return 0;
}

2-8:子序列的和
输入两个正整数n

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define maxn 10000

int main()
{
  double n,m;
  double sum=0;
  scanf("%lf%lf",&n,&m);
  for(double i=n;i<=m;i++)
  {
    sum+=1.0/(i*i);
  }
  printf("%.5lf\n",sum);
  return 0;
}

**此题有陷阱,如果将i定义为int型,则会发生乘法溢出的错误,故定义为double型
int取值范围:-2147483648~2147483647
double型取值范围:-1.7*10^-308~1.7*10^-308;

2-9:分数化小数
输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b<=10^6,c<100.
例如a=1,b=6,c=4时应输出0.1667;

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define maxn 10000

int main()
{
  int a,b,c;
  scanf("%d%d%d",&a,&b,&c);
  printf("%.*lf\n",c,a*1.0/b);
  return 0;
}

**小数点保留到固定位的输出函数:printf(“%.*lf\n”,c,a*1.0/b);

下题为转载
2-10:排列
用 1,2,3,….,9组成3个三位数abc,def,和ghi,每个数字恰好使用1次,要求 abc:def:ghi=1:2:3.
输出所有解。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

int m[10];
int main()
{
  int a,b,c,cc,x,y,z;
  for(a=123;a<=333;a++)
  {
    memset(m,0,sizeof(m));
    x=a;
    b=2*a,y=b;
    c=3*a,z=c;
    int flag=0;
    while(x>0)
    {
      cc=x%10;x/=10;
      if(cc!=0&&m[cc]==0)
        m[cc]++;
      else
      {
        flag=1;
        break;
      }
    }
    if(flag)
        continue;
    while(y>0)
    {
      cc=y%10;y/=10;
      if(cc!=0&&m[cc]==0)
        m[cc]++;
      else
      {
        flag=1;
        break;
      }
    }
    if(flag)
        continue;
    while(z>0)
    {
      cc=z%10;z/=10;
      if(cc!=0&&m[cc]==0)
        m[cc]++;
      else
      {
        flag=1;
        break;
      }
    }
    if(flag==0)
        printf("%d %d %d\n",a,b,c);
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值