C/C++语言经典算法题_东方旅行者的博客-程序员宝宝_c++算法题

技术标签: C++  c++  C语言  c语言  

一、有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

#include <stdio.h>
int main(){
    
    int month,temp1,temp2;
    month=temp1=temp2=2;
    printf("第1个月兔子数量为2\n");
    printf("第2个月兔子数量为2\n");
    while(month<20){
    
        month++;
        int temp=temp2;
        temp2=temp1+temp2;
        temp1=temp;
        printf("第%d个月兔子数量为%d\n",month,temp2);
    }
    return 0;
}

二、判断101-200之间有多少个素数,并输出所有素数

#include <stdio.h>
#define bool int
#define true 1
#define false 0
bool isPrime(int num){
    
    for(int i=2;i*i<=num;i++)
        if(num%i==0)
            return false;
    return true;
}
int main(){
    
    int sum=0;
    for(int i=101;i<=200;i++)
    if(isPrime(i)){
    
        sum++;
        printf("%d是素数\n",i);
    }
    printf("自101到200之间一共有%d个素数\n",sum);
    return 0;
}

三、打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身

#include <stdio.h>
#define bool int
#define true 1
#define false 0
bool isTure(int num){
    
    int h=num/100;
    int t=(num-h*100)/10;
    int s=num%10;
    if(s*s*s+t*t*t+h*h*h==num) return true;
    return false;
}
int main(){
    
    for(int i=100;i<=999;i++)
        if(isTure(i)) printf("水仙花数:%d\n",i);
    return 0;
}

四、将一个正整数分解质因数
从最小质数2开始,若当前剩余数字能整除该候选因数,则当前数字等于当前数字除以该质因数,并输出,否则因数加一

#include <stdio.h>
#define bool int
#define true 1
#define false 0
bool isPrime(int num){
    
    for(int i=2;i*i<=num;i++)
        if(num%i==0) return false;
    return true;
}
int main(){
    
    int num;int d=2;
    scanf("%d",&num);
    while(num>1){
    
        if(num%d==0&&isPrime(d)){
    
            num=num/d;
            printf("%d",d);
            if(num>1)
                printf("*");
        }
        else d++;
    }
    return 0;
}

五、利用条件运算符的嵌套:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示

#include <stdio.h>
int main(){
    
    int mark;
    scanf("%d",&mark);
    (mark>=90)?printf("A\n"):((mark>=60)?printf("B\n"):printf("C\n"));
    return 0;
}

六、输入两个正整数m和n,求其最大公约数和最小公倍数
最大公因数使用辗除法:假设用f(x, y)表示x,y的最大公约数,则有f(x, y)=f(y, x%y)当x%y等于0时代表y就是原始两个数的最大公因数
算法步骤:

  1. 若n不等于0则进行2,否则3
  2. 令n等于m%n,令m等于原先的n,返回2进行判断
  3. 输出m,程序结束

最小公倍数使用两数之积除以最大公因数

#include <stdio.h>
/*最大公因数计算函数*/
int getGCD(int m,int n){
    
    while(n!=0){
    
        int temp=m%n;
        m=n;
        n=temp;
    }
    return m;
}
/*最小公倍数计算函数*/
int getLCM(int n1,int n2){
    return n1*n2/getGCD(n1,n2);}

int main(){
    
    int n1,n2;
    scanf("%d %d",&n1,&n2);
    printf("最大公因数为:%d\n",getGCD(n1,n2));
    printf("最小公倍数为:%d\n",getLCM(n1,n2));
    return 0;
}

七、输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个

#include <stdio.h>
int main(){
    
    int cNum,bNum,mNum,elseNum;
    char c;
    cNum=bNum=mNum=elseNum=0;
    while(){
    
        c=getchar();
        if(c=='\n') break;
        if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))  cNum++;
        else if(c==' ')                         bNum++;
        else if(c>='0'&&c<='9')                 mNum++;
        else                                    elseNum++;
    }
    printf("字母个数为:%d\n",cNum);
    printf("空格个数为:%d\n",bNum);
    printf("数字个数为:%d\n",mNum);
    printf("其它字符个数为:%d\n",elseNum);
    return 0;
}

八、求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字,a与a重复最大次数由用户输入
注意sum使用float,不然结果会错误

#include <stdio.h>
#include <math.h>
int main(){
    
    int num,round;
    float sum=0;
    scanf("%d %d",&num,&round);
    for(int i=0;i<round;i++)
        for(int j=0;j<=i;j++)
            sum+=num*pow(10,j);
    printf("%.0f",sum);
    return 0;
}

九、一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2
+3。编程找出1000以内的所有完数

#include <stdio.h>
int main(){
    
    for(int i=1;i<=1000;i++){
    
        int sum=0;
        for(int j=1;j<i;j++)
            if(i%j==0)  sum+=j;
        if(sum==i)  printf("%d\n",i);
    }
    return 0;
}

十、一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?

#include <stdio.h>
int main(){
    
    double oriHeight=100;
    double totalHeight=0;
    for(int i=0;i<10;i++){
    
        totalHeight+=oriHeight;
        if(i==9)    printf("第10次落地共经过%.10lf米\n",totalHeight);
        oriHeight=oriHeight/2;
        if(i==9)    printf("第10次反弹%.10lf米\n",oriHeight);
        totalHeight+=oriHeight;
    }
    return 0;
}

十一、一只猴子摘了N个桃子第一天吃了一半又多吃了一个,第二天又吃了余下的一半又多吃了一个,到第十天的时候发现还有一个。求第一天桃子数量。

#include <stdio.h>
int main(){
    
    int num=1;
    for(int i=1;i<10;i++)   num=(num+1)*2;
    printf("第一天的桃子数量:%d",num);
}

十二、使用牛顿迭代法求一个数字的正平方根
牛顿迭代法求平方根迭代公式
牛顿迭代法:本质是求f(x)=0的根,迭代方式为
在这里插入图片描述
所以再求一个数A的平方根的时候,f(x)=x2-A=0,而不是f(x)=x2

#include <stdio.h>
#include<math.h>
#define Epsilon 1.0E-9 /*控制精度*/
int main(){
    
    double num,x0,x1;
    scanf("%lf",&num);
    x0=num/2;
    x1=(num/x0+x0)/2;
    while(fabs(x1-x0)>=Epsilon){
    
        x0=x1;
        x1=(num/x0+x0)/2;
    }
    printf("%lf的平方根为:%.3lf",num,x1);
}

十三、牛顿迭代法求方程 2x3-4x2+3x-6 的一个根

#include <stdio.h>
#include<math.h>
#define Epsilon 1.0E-6 /*控制解的精度*/
int main(){
    
    float x0,x1=1.5;
    x1=(4*x0*x0*x0-4*x0*x0+6)/(6*x0*x0-8*x0+3);
    while(fabs(x1-x0)>=Epsilon){
    
        x0=x1;
        x1=(4*x0*x0*x0-4*x0*x0+6)/(6*x0*x0-8*x0+3);
    }
    printf("方程的根为%.3f\n",x1);
    return 0;
}

十四、输入数字n,然后输入一个n位的数字num,判断num是否是回文数

#include <stdio.h>
#include<math.h>
int main(){
    
    int len;
    double sum,rsum;sum=rsum=0;
    scanf("%d",&len);
    char num[len];
    for(int i=0;i<len;i++){
    
        num[i]=getchar();
        while(num[i]<'0'||num[i]>'9')
            num[i]=getchar();
        sum+=(num[i]-48)*pow(10,len-1-i);
    }
    for(int i=len-1;i>=0;i--)
        rsum+=(num[i]-48)*pow(10,i);
    if(sum==rsum)   printf("%.0lf是回文数\n",sum);
    else            printf("%.0lf不是回文数\n",sum);
}

十五、求100之内的素数

#include <stdio.h>
#define bool int
#define true 1
#define false 0
bool isPrime(int num){
    
    if(num<=1) return false;
    for(int i=2;i*i<=num;i++)
        if(num%i==0) return false;
    return true;
}
int main(){
    
    for(int i=1;i<=100;i++)
        if(isPrime(i))	printf("%d是素数\n",i);
    return 0;
}

十六、画出心形图案,心形线公式(x2+y2-1)3-x2y3=0,心形内部(包括边界)公式小于等于零

#include <stdio.h>
int main() {
    
    for(float y = 1.5; y > -1.5; y -= 0.1){
    
        for(float x = -1.5; x < 1.5; x += 0.05){
    
            float a = x * x + y * y - 1;
            putchar(a * a * a - x * x * y * y * y <= 0.0 ? '*' : ' ');
        }
        putchar('\n');
    }
}

结果:
在这里插入图片描述
十七、字符串去特定字符
题目链接,注意:当使用gets函数时,函数会读取换行符,并停止函数,所以不需要单独一个getchar来处理换行符,但当使用scanf时,scanf会将换行符留给下次操作处理,所以当使用scanf时需要加一个getchar函数来处理换行符。另外输出字符时,需要判断是否已经到了‘\0’空字符,也就是字符串结尾,如果是的话则跳出循环。

#include <stdio.h>
int main(){
    
    char c,str[1000];
    gets(str);
    c=getchar();
    for(int i=0;i<1000;i++)
        if(str[i]==c)                       continue;
        else if(str[i]!=c&&str[i]!='\0')    printf("%c",str[i]);
        else                                break;
    return 0;
}

十八、字符串连接,不用strcat 函数

#include <stdio.h>
static char result[2000];
char* myStrCat(char* str1,char* str2){
    
    int i=0,j=0;
    while(str1[j]!='\0')    result[i++]=str1[j++];
    j=0;
    while(str2[j]!='\0')    result[i++]=str2[j++];
    result[i]='\0';
    return result;
}
int main(){
    
    char str1[1000],str2[1000];
    gets(str1);gets(str2);
    char* p=myStrCat(str1,str2);
    printf("%s\n",p);
    return 0;
}

十九、输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串

#include <stdio.h>
#include <string.h>
static char str[200];
void sort(int low, int high){
    
    if (low < high){
    
        int i = low;
        int j = high;
        int k = str[low];
        while (i < j){
    
            while(i < j && str[j] >= k)	j--;
            if(i < j)	str[i++] = str[j];
            while(i < j && str[i] < k)	i++;
            if(i < j)	str[j--] = str[i];
        }
        str[i] = k;
        sort(low, i - 1);
        sort(i + 1, high);
    }
}
int main(){
    
    gets(str);
    printf("原字符串:%s\n",str);
    sort(0,strlen(str)-1);
    printf("排序后字符串:%s\n",str);
    return 0;
}

结果:

[email protected]!:SQS
原字符串:[email protected]!:SQS
排序后字符串:!!:@AAAAQSSSSaaaddss

二十、已知不等式1!+ 2!+… + m!<n, 对用户指定的n值,输出满足该不等式m的最大整数解
TIP:使用一个变量记录第i次计算阶乘时第i-1次的阶乘结果,能够缩短计算时间,减少运行时间

#include <stdio.h>
int main(){
    
    int n,m,sum,temp;
    m=sum=0;temp=1;
    scanf("%d",&n);
    for(m=1;;m++){
    
        temp*=m;
        sum+=temp;
        if(sum>=n)  break;
    }
    printf("m:%d\n",m-1);
    return 0;
}

二十一、用小于等于n元去买100只鸡,A鸡5元/只,B鸡3元/只,C鸡1/3元/只,分别记为x只,y只,z只,求解x,y,z所有可能解,对于每组输入,请输出x,y,z所有可行解,按照x,y,z依次增大的顺序输出。

#include <stdio.h>
int main(){
    
    int x,y,z,n;
    scanf("%d",&n);
    for(x=0; x<=n/5; x++)
        for(y=0; y<=n/3; y++)
            for(z=0; z<=n*3; z++)
                if(x+y+z==100&&5*x+3*y+z/3.0<=n)
                    printf("x=%d,y=%d,z=%d\n",x,y,z);
    return 0;
}

二十二、一个百万富翁遇到一个陌生人,陌生人找他谈了一个换钱的计划。该计划如下:我每天给你10万元,你第一天给我1分钱,第二天2分钱,第三天4分钱……这样交换 30 天后,百万富翁交出了多少钱?陌生人交出了多少钱?

#include <stdio.h>
int main(){
    
    long sum=0;
    long money=1;
    for(int i=0; i<30; i++){
    
        sum+=money;
        money*=2;
    }
    printf("百万富翁交出的钱:300万元\n");
    printf("陌生人交出的钱:%f万元\n",sum/1000000.0);
    return 0;
}

二十三、输入一个数n,然后输入n个各不相同的数,调换数组中最大和最小的两个数,然后输出

#include <stdio.h>
int main(){
    
    int n,min,max,temp;
    scanf("%d",&n);
    int arr[n];
    min=max=0;
    for(int i=0; i<n; i++){
    
        scanf("%d",&arr[i]);
        if(arr[min]>arr[i]) min=i;
        if(arr[max]<arr[i]) max=i;
    }
    temp=arr[min];
    arr[min]=arr[max];
    arr[max]=temp;
    for(int i=0; i<n; i++)
        if(i!=n-1)  printf("%d ",arr[i]);
        else        printf("%d\n",arr[i]);
    return 0;
}

二十四、给定三角形的三条边a、b、c。判断是否能组成三角形,若能组成则判断该三角形类型(锐角、直角、钝角)
思路:使用勾股定理:若最大边的平方大于两小边平方和,则是钝角三角形;若最大边的平方等于两小边平方和,则是直角三角形;若最大边的平方小于两小边平方和,则是锐角三角形。

#include <stdio.h>
void judge(int a, int b, int c){
    
    int temp=a;
    a=a>b?a:b;
    b=a==b?temp:b;
    temp=a;
    a=a>c?a:c;
    c=a==c?temp:c;
    if(a>=(b+c))            printf("无法组成三角形\n");
    else if(a*a>(b*b+c*c))  printf("该三角形是钝角三角形\n");
    else if(a*a==(b*b+c*c)) printf("该三角形是直角三角形\n");
    else                    printf("该三角形是锐角三角形\n");
}
int main(){
    
    int a,b,c;
    scanf("%d %d %d",&a,&b,&c);
    judge(a, b, c);
    return 0;
}

二十五、输入两个整数a和b,计算a+b的和。注意此题是多组测试数据,以在Windows下,用户按下CTRL+Z(会看到一个^Z字符)再按下回车(可能需要重复多次),表示输入结束;Linux/Unix下使用CTRL+D表示输入结束。
思路:scanf()函数返回值分为3种:

  1. 返回正整数。表示正确输入参数的个数
  2. 返回整数0。表示用户的输入不匹配,无法正确输入任何值
  3. 返回-1。表示输入流已经结束。在Windows下,用户按下CTRL+Z(会看到一个^Z字符)再按下回车(可能需要重复多次),就表示输入结束;Linux/Unix下使用CTRL+D表示输入结束
#include<stdio.h>
int main(){
    
    int a,b;
    while(scanf("%d%d", &a, &b)!=-1)	printf("%d\n",a+b);
    return 0;
}

二十六、有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
思路:递推数列,类似于斐波那契额数列。前四年每一年的牛数量等于年数,四年以后从第五年开始第i年等于第n-1年加第n-3年

#include<stdio.h>
int arr[55];
void cal(){
    
    for(int i=0; i<55; i++)
        if(i<=4)    arr[i]=i;
        else        arr[i]=arr[i-1]+arr[i-3];
}
int main(){
    
    cal();
    int temp;
    while(1){
    
        scanf("%d",&temp);
        if(!temp)   break;
        printf("%d\n",arr[temp]);
    }
    return 0;
}

二十七,给定一元二次方程的a,b,c,求解ax2+bx+c=0的解。当b2-4ac小于0时,求出其虚数解。(结果的实部和虚部都保留3位小数)
解析:用bool型变量flag表明Δ是否小于0.若小于零,则最后输出的虚部后面需要加上i

#include<stdio.h>
#include<math.h>
#include<stdbool.h>
int main(void){
    
    int a,b,c;
    bool flag=true;
    scanf("%d %d %d",&a,&b,&c);
    double RP=(double)(-b)/(2*a);
    if(b*b-4*a*c<0) flag=false;
    double IP=(double)sqrt(fabs(b*b-4*a*c))/(2*a);
    if(flag)    printf("%.3lf %.3lf\n",RP+IP,RP-IP);
    else        printf("x1=%.3lf+%.3lfi x2=%.3lf-%.3lfi\n",RP,IP,RP,IP);
    return 0;
}

测试结果:

4 1 1
x1=-0.125+0.484i x2=-0.125-0.484i

二十八、输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写三个函数;①输入10个数;②进行处理;③输出10个数。
注意最后在交换元素时,可能在交换第0元素与最小元素时最大元素索引会改变,因为最大元素可能在第0号元素。

#include<stdio.h>
int arr[10];
int min=0;max=0,minIndex=-1,maxIndex=-1;
void getNum(){
    
    for(int i=0;i<10;i++){
    
        scanf("%d",&arr[i]);
        if(minIndex==-1) {
    min=arr[i]; minIndex=i; max=arr[i]; maxIndex=i;}
        else{
    
            if(arr[i]<min)  {
    min=arr[i];    minIndex=i;}
            if(arr[i]>max)  {
    max=arr[i];    maxIndex=i;}
        }
    }
}
void cal(){
    
    int temp1=arr[0],temp2=arr[9];
    arr[0]=min;
    arr[minIndex]=temp1;
    if(maxIndex==0) maxIndex=minIndex;
    arr[9]=arr[maxIndex];
    arr[maxIndex]=temp2;
}
void show(){
    
    for(int i=0;i<10;i++)
        printf("%d ",arr[i]);
}
int main(void){
    
    getNum();
    cal();
    show();
    return 0;
}

二十九、有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串。
注意:使用getchar()吸收gets()函数调用之前的换行符,因为gets()不会忽略前面的空白

#include<stdio.h>
char newStr[100];
void cpy(char* str, int n, int m){
    
    int index=0;
    for(int i=m-1;i<n;i++)
        newStr[index++]=str[i];
    newStr[index]='\0';
}
int main(void){
    
    int n,m;
    scanf("%d",&n);
    getchar();
    char str[n+1];
    gets(str);
    scanf("%d",&m);
    cpy(str,n,m);
    printf("%s\n",newStr);
    return 0;
}

三十、定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。
样例输入:2000 12 31
样例输出:366

#include<stdio.h>
int days[12]={
    31,28,31,30,31,30,31,31,30,31,30,31};
struct date{
    
    int year;
    int month;
    int day;
};
int isLeapYear(int year){
    
    if(year%400==0||(year%4==0&&year%100!=0))   return 1;
    return 0;
}
void cal(struct date myDate){
    
    int result=0;
    if(isLeapYear(myDate.year)) days[1]=29;
    for(int i=0;i<myDate.month-1;i++)
        result+=days[i];
    result+=myDate.day;
    printf("%d\n",result);
}

int main(void){
    
    struct date myDate;
    scanf("%d %d %d",&myDate.year,&myDate.month,&myDate.day);
    cal(myDate);
    return 0;
}

三十一、现有有N个学生的数据记录,每个记录包括学号、姓名、三科成绩。 编写一个函数input,用来输入一个学生的数据记录。 编写一个函数print,打印一个学生的数据记录。 在主函数调用这两个函数,读取N条记录输入,再按要求输出。 N<100。
样例输入

2
a100 clang 70 80 90
b200 dotcpp 90 85 75

样例输出

a100,clang,70,80,90
b200,dotcpp,90,85,75
#include<stdio.h>
struct student{
    
    char id[100];
    char name[100];
    int mark1;
    int mark2;
    int mark3;
};
void input(struct student* p){
    
    scanf("%s %s %d %d %d",p->id,p->name,&(p->mark1),&(p->mark2),&(p->mark3));
}
void print(struct student* p){
    
    printf("%s,%s,%d,%d,%d\n",p->id,p->name,p->mark1,p->mark2,p->mark3);
}
int main(void){
    
    int n;
    scanf("%d",&n);
    struct student arr[n];
    getchar();
    for(int i=0;i<n;i++){
    
        input(&arr[i]);
        getchar();
    }
    for(int i=0;i<n;i++){
    
        print(&arr[i]);
    }
    return 0;
}

三十二、已有a、b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。第一行,a、b两个链表元素的数量N、M,用空格隔开。 接下来N行是a的数据 然后M行是b的数据 每行数据由学号和成绩两部分组成。
题目OJ地址
样例输入

2 3
5 100
6 89
3 82
4 95
2 10

样例输出

2 10
3 82
4 95
5 100
6 89
#include <stdio.h>
#include <stdlib.h>
typedef struct Stu{
    
    int id;
    int score;
    struct Stu* next;
}Stu;
Stu* create(int n){
    
    Stu* head = malloc(sizeof(Stu));
    head->id=-1;
    head->score=-1;
    head->next=NULL;
    for(int i=0;i<n;i++){
    
        Stu* newStu=malloc(sizeof(Stu));
        scanf("%d %d",&newStu->id,&newStu->score);
        newStu->next=NULL;
        if(head->id==-1)    head=newStu;
        else                {
    newStu->next=head;  head=newStu;}
    }
    return head;
}
Stu* merge(Stu* s1, Stu* s2){
    
    Stu* p=s1;
    while(p->next!=NULL)    p=p->next;
    p->next=s2;
    return s1;
}
void sort(Stu* s){
    
    for(Stu* i=s;i!=NULL;i=i->next)
        for(Stu* j=i;j!=NULL;j=j->next){
    
            if(i->id>j->id){
    
                int idTemp=i->id;
                int scoreTemp=i->score;
                i->id=j->id;
                i->score=j->score;
                j->id=idTemp;
                j->score=scoreTemp;
            }
        }
}
void print(Stu* s){
    
    while(s!=NULL){
    
        printf("%d %d\n",s->id,s->score);
        s=s->next;
    }
}
int main(){
    
    int N, M;
    scanf("%d %d",&N,&M);
    Stu* students1=create(N);
    Stu* students2=create(M);
    students1=merge(students1, students2);
    sort(students1);
    print(students1);
    return 0;
}

三十三、数字整除 OJ网址
定理:把一个至少两位的正整数的个位数字去掉,再从余下的数中减去个位数的5倍。当且仅当差是17的倍数时,原数也是17的倍数。例如,34是17的倍数,因为3-20=-17是17的倍数;201不是17的倍数,因为20-5=15不是17的倍数。输入一个正整数n,你的任务是判断它是否是17的倍数。

思路:对于大整数,不要将其完全读入一个字符串中,而是模拟除法,一位一位读取,没读取一位就计算其与17的余数

样例输入

34
201
2098765413
1717171717171717171717171717171717171717171717171718
0

样例输出

1
0
1
0
#include<stdio.h>
int main(){
    
    int num=0;
    char c;
    c=getchar();
    while(1){
    
        while(c!='\n'){
    
            num=num*10+c-'0';
            num%=17;
            c=getchar();
        }
        if(num==0)  printf("1\n");
        else        printf("0\n");
        num=0;
        c=getchar();
        if(c=='0')  return 0;
    }
    return 0;
}

三十四、循环节
描述:https://www.dotcpp.com/oj/problem1101.html
参考:https://blog.dotcpp.com/a/61187

#include <iostream>
#include <cstring>
using namespace std;
int k;
void mul(int* a,int b,int* c){
    //高精低乘
    for(int i=0;i<=k;i++)c[i]=0;
    int cou=0;
    for(int i=1;i<=k;i++){
    
        c[i]=a[i]*b+cou;
        cou=c[i]/10;
        c[i]%=10;
    }
}
void mult(int *a,int* b,int* c){
    //高精高乘
    for(int i=0;i<=k;i++)c[i]=0;
    for(int i=1;i<=k;i++)
        for(int j=1;i+j-1<=k;j++)
            c[j+i-1]+=a[j]*b[i];
    int cou=0;int go=0;
    for(int i=1;i<=k;i++){
    
        go=c[i]+cou;
        c[i]=go%10;
        cou=go/10;
    }
}
int main(){
    
    string s;
    cin>>s>>k;//读入数据,建议用string类型读入,使用int会WA
    //将字符串转换成整型数组存储
    int ss=s.size();
    int n[ss+1],//存储n
        n0[k+1],//只取n的后k位,该数组用于比较进行每一位的循环匹配
        c0[k+1],//每次累乘的结果
        c1[k+1],//每次累乘的乘数一
        c2[k+1],//每次累乘的乘数二
        c3[k+1];//n的循环节次幂再乘以n存放于该数组再与n0进行匹配,即c3=c0*n
    //将字符串转换成整型数组,注意顺序颠倒
    for(int i=0;i<ss;i++)
        n[ss-i]=s[i]-'0';
    //对数组进行初始化
    for(int i=1;i<=k;i++)
        if(i<=ss)
            c2[i]=c1[i]=c0[i]=n0[i]=n[i];
        else
            c2[i]=c1[i]=c0[i]=n0[i]=0;
    //存储循环节的数组nowc,其nowcc是辅助数组
    int nowc[101],nowcc[101];
    memset(nowc,0,sizeof(nowc));
    memset(nowcc,0,sizeof(nowcc));
    nowc[1]=nowcc[1]=1;
    for(int i=1;i<=k;i++){
    
        for(int j=1;j<=11;j++){
    
            mult(c0,n,c3);//n的已计算出的循环节次幂存储在c0,再乘以n得到要匹配的值
            if(c3[i]==n0[i]){
    
                mul(nowc,j,nowcc);//更行循环节
                copy(nowcc,nowcc+101,nowc);
                copy(c0,c0+k+1,c2);//更新乘数二
                break;
            }
            else if(j==11){
    //没有循环节
                cout<<-1<<endl;
                return 0;
            }
            //累乘
            mult(c1,c2,c0);
            copy(c0,c0+k+1,c1);
        }
    }
    //去除前导0,输出答案
    int ii;
    for(ii=100;ii>=1&&nowc[ii]==0;ii--);
    while(ii>0)
        cout<<nowcc[ii--];
    return 0;
}

三十五、守望者的逃离
描述:https://www.dotcpp.com/oj/problem1108.html
思路:贪心

#include<iostream>
using namespace std;
int main(){
    
    int m,s,t,copy,flash=0,dis=0;
    cin>>m>>s>>t;
    copy=t;
    while((t--)!=0){
    
        /*闪现距离*/
        if(m>=10){
    
            flash+=60;
            m-=10;
        }
        else    m+=4;
        /*跑步距离*/
        dis+=17;
        /*
        当前这一秒结束时,
        比较跑步距离与闪现距离相对大小,
        将跑步距离设为较大的
        */
        if(flash>dis)   dis=flash;
        if(dis>=s){
    
            cout<<"Yes"<<endl<<copy-t<<endl;
            return 0;
        }
    }
    cout<<"No"<<endl<<dis<<endl;
    return 0;
}

三十六、使用纸和剪刀,通过以下方式切出两个面以形成圆柱体:水平切纸(平行于短边)以得到两个矩形部分。从第一部分开始,切出一个最大半径的圆。 圆圈将形成圆柱体的底部。将第二部分卷起来,使其周长与圆的周长相等,然后将卷的一端连接到圆上。 请注意,卷筒可能会有一些重叠的部分,以便获得所需的周长。在给定纸张尺寸的情况下,计算出可以使用上述步骤构造的最大量的滚筒?结果保留3位小数
OJ地址:https://www.dotcpp.com/oj/problem1111.html

注意:保留几位小数使用#include <iomanip>头文件,并在cout中使用fixed<<setprecision(3)控制小数点后三位小数,如果不加fixed,则会保留三位有效数字
思路:
在这里插入图片描述

#include<iostream>
#include<algorithm>
#include <iomanip>
#define pi 3.141592653589793238
using namespace std;
double cal(double w,double h){
    
    double r=h/(2*(pi+1));
    if(r>w/2)   r=w/2;
    double result1=pi*r*r*w;
    r=w/(2*pi);
    double result2=pi*r*r*(h-2*r);
    cout<<fixed<<setprecision(3)<<max(result1,result2)<<endl;
}
int main(){
    
    double w,h;
    cin>>w>>h;
    while(!(w==0&&h==0)){
    
        cal(w,h);
        cin>>w>>h;
    }
    return 0;;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43270828/article/details/104814190

智能推荐

Virtual-Network--—DHCP协议学习以及对应报文分析_海渊_haiyuan的博客-程序员宝宝_dhcp客户端成功获取ip地址后,在地址使用租期过去1/2时,后续如何操作?

文章目录Virtual-Network--—DHCP协议学习以及对应报文分析转载1. DHCP 简介1.1 DHCP 作用1.2 DHCP 工作机制2. DHCP 交互流程2.1 正常交互流程2.2 租约2.3 客户端状态机**2.4 参数配置**3. DHCP 报文3.1 报文类型3.2 报文格式3.3 抓包4. DHCP 中继代理Virtual-Network–—DHCP协议学习以及对应报...

2019西安邀请赛D_Miku and Generals(二分图+01背包)_GoghV的博客-程序员宝宝

这道题先建图,然后把联通子块染色,一个联通子块染成两个颜色,然后01背白就可。如果总和为2X,那么每个连通子块小的那个加起来后的和为Y,那么(X-Y)就是剩下的可以操作的空间,然后求每个联通子块两个部分的差值b[MAX_V],在(X-Y)里做b[MAX_V]的01背包,求一个最大值dp[m],再加上(X-Y)就是其中一个的值,然后用总的输出max(sum-(X-Y)-dp[m],(X-Y)+dp...

error怎么开机 fan_台式机开机出现cpu fan error怎么办_weixin_39979080的博客-程序员宝宝

每次开机我的台式机都出现cpu fan error,这是什么原因呢?小编告诉你!解决下面由学习啦小编给你做出详细的台式机开机出现cpu fan error解决方法介绍!希望对你有帮助!台式机开机出现cpu fan error解决方法一:英文意思是CPU风扇错误,意指BIOS没有检测到CPU风扇,原因可能是当前计算机系统安装的CPU风扇是没有测速芯片的简易版(山寨风扇),或CPU风扇已停传。具体情况...

Python中 ''.JOIN()的用法_zyh的打怪历程的博客-程序员宝宝_.join()

Python join()方法描述将序列中的元素以指定的字符连接生成一个新的字符串。

随便推点

绝对不容错过的野生动物wildlife摄影作品_weixin_34402408的博客-程序员宝宝

为什么80%的码农都做不了架构师?&gt;&gt;&gt; ...

攻城狮成长日记-----关于为移动端做后台的二三事_w741998232的博客-程序员宝宝

今天决定开始写下自己在软件开发这个行业中的点点滴滴,一般会记录自己在项目中学到的知识和遇到的bug及解决方式,算是有个记录,也为后来的程序猿们提供个方便. 第一篇写的是java做移动端后台的项目,据我了解移动端分为两种模式,一种是类浏览器模式,在APP端基本不做任何逻辑处理,所有页面和逻辑都由PC端的后台来做,这种模式的优点是适配性强,开发一套后台安卓和IOS都可以使用,缺点也显而易见

PAT乙级 1055 集体照 (25 分) C语言_Ronaldo777777的博客-程序员宝宝

一、题目二、源代码#include&lt;stdio.h&gt;#include &lt;string.h&gt;#include &lt;stdlib.h&gt;struct Student{ char name[9]; int height;};int cmp(const void *a, const void *b){ int i,j,aa,bb; struct Student *c = (struct Student *)a; struc

Postgresql管理系列-第九章 WAL(Write Ahead Logging)介绍_魂醉的博客-程序员宝宝_postgres ahead log

事务日志是数据库的重要组成部分,因为即使数据库发生系统故障,也要求所有数据库管理系统不能丢失任何数据。它是数据库系统中所有更改和操作的历史记录日志,以确保没有数据因故障而丢失,例如电源故障或导致服务器崩溃的其他服务器故障。由于日志包含有关已执行的每个事务充足的信息,因此数据库服务器应能够通过在服务器崩溃时重放事务日志中的更改和操作来恢复数据库集群。在计算机科学领域,WAL是Write Ahead...

ES Java API - 获取索引历史更新数据_爱吃西蓝花的老张的博客-程序员宝宝

承接上一篇中获取client实例 /** * 聚合查询 分桶信息 * @param index */ public static String getHistoryDateCounts(String index){ //SearchRequestBuilder sbuilder = client.prepareSearch(index).

Etag 是什么_ok7758521ok的博客-程序员宝宝

 Etag 是URL的Entity Tag,用于标示URL对象是否改变,区分不同语言和Session等等。具体内部含义是使服务器控制的,就像Cookie那样。它有一些好处和特点:1、有些URL是多语言的网页,相同的URL会返回不同的东东。还有不同的Session有不同的Cookie也就有不同的内容。这种情况下如果过 Proxy,Proxy就无法区分导致串门,只能简单的取消cache功能。Etag解

推荐文章

热门文章

相关标签