C/C++语言经典算法题

7 篇文章 2 订阅

一、有一对兔子,从出生后第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;
}

结果:

dadASAASAsasa!@!:SQS
原字符串:dadASAASAsasa!@!: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;;
}
  • 9
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值