2024西北工业大学noj(C语言)记录全100题

目前已将全部题目记录

作者是零基础捏,作个人学习记录 ,也供大家参考
有些题目即使AC了但未必严谨
有错误请务必指正我
我做完之后会看去年学长发的贴子,各位可以直接看他们的,有些打的注解就是看过他们的文章后加入的。
如果各位有优解可以在评论区或者私信教我hh

其中一位的传送门在此https://blog.csdn.net/2302_80002065/article/details/135132048(已获得授权)
另一位的在这https://blog.csdn.net/annesede/article/details/133761873(已获得授权),
然后这里是他的易错总结https://annesede.github.io/p/nojc%E6%98%93%E9%94%99%E6%80%BB%E7%BB%93/
感谢佬们的支持!

1-10水题

1.Hello World

#include<stdio.h>
int main()
{
    printf("Hello World");
    return 0;
}

2.A+B

#include<stdio.h>
int main()
{
    int a,b;
    scanf("%d %d",&a,&b);
    printf("%d",a+b);
    return 0;
}

3.数据类型大小及范围

#include<stdio.h>
int main()
{
    int d;
    scanf("%d",&d);
    switch(d){
    case 1:printf("1,-128,127");break;
    case 2:printf("1,0,255");break;
    case 3:printf("2,32768,32767");break;
    case 5:printf("4,-2147483648,2147483647");break;
    case 6:printf("4,0,4294967295");break;
    case 7:printf("4,-2147483648,2147483647");break;
    case 8:printf("4,0,4294967295");break;
    case 9:printf("8,-9223372036854775808,9223372036854775807");break;
    case 10:printf("8,0,18446744073709551615");break;
    }
return 0;
}

做这题的时候还不会sizeof(),用生命代替计算机计算了说是。
补:从大佬们那里学到可以用C语言标准库<limits.h>来做,省去手敲数字部分。

4.均值

#include<stdio.h>
int main()
{
    long long int a,b,c;
    scanf("%lld %lld",&a,&b);
    c=a+(b-a)/2;
    printf("%lld",c);
    return 0;
}

用a+(b-a)/2(这里的“/2”你用位运算符“>>1”也OK)是为了防止溢出,其实我用int类型(a+b)/2也AC了hh.

5.进制转换

#include<stdio.h>
int main()
{
    unsigned a;
    scanf("%u",&a);
    printf("%X,%o",a,a);
    return 0;
}

6.浮点数输出

#include<stdio.h>
int main()
{
    double a;
    scanf("%lf",&a);
    printf("%.6lf,%.2lf,%.8lf",a,a,a);
    return 0;
}

7.动态宽度输出

#include<stdio.h>
int main()
{
    int m,n;
    scanf("%d %d",&m,&n);
    printf("%0*d",n,m);
    return 0;
}

8.计算地球上两点之间的距离

#include<stdio.h>
#include<math.h>
#define PI 3.1415926
double hav(double x);
double cha(double x){
    return x*PI/180.0;
}
double func(double a,double b,double c,double d){
    return 6371*acos(1-2*((hav(c-a))+cos(a)*cos(c)*hav(d-b)));
}
int main()
{
    double a,b,c,d;
    scanf("%lf %lf",&a,&b);
    scanf("%lf %lf",&c,&d);
    printf("%.4lfkm",func(cha(a),cha(b),cha(c),cha(d)));
    return 0;
}
double hav(double x){
 return sin(x/2)*sin(x/2);
}

输入的是角度,记得转弧度。

9.风寒指数

#include<stdio.h>
#include<math.h>
int chill(double x,double y)
{
    double b=13.12+0.6215*y-11.37*pow(x,0.16)+0.3965*y*pow(x,0.16);
     int a=(int)(b+0.5);
    return a;
}
int main()
{
    double a,b;
    scanf("%lf %lf",&a,&b);
    printf("%d",chill(a,b));
    return 0;
}

图看半天,就下面一行公式有用,麻

10.颜色模型转换

#include<stdio.h>
double max(double x,double y,double z){
    return a>=b?(a>=c?a:c):(b>=c?b:c);
 }
double min(double x,double y,double z){
    return a<=b?(a<=c?a:c):(b<=c?b:c);
}
int main()
{
    double R,G,B;
    double V,S,H,M,I;
    scanf("%lf %lf %lf",&R,&G,&B);
    R=R/255;G=G/255;B=B/255;
    M=max(R,G,B);
    I=min(R,G,B);
    V=M;
    S=(M-I)/M;
    if(M==R){
        H=60*(G-B)/(M-I);
    }
    else if(M==G){
        H=60*(2+(B-R)/(M-I));
    }
    else H=60*(4+(R-G)/(M-I));
    if(H<0) H=H+360;
    printf("%.4lf,%.4lf%%,%.4lf%%",H,S*100.0,V*100.0);
    return 0;
}

11-20循环

11.操作数

#include<stdio.h>
int wei(int x){
    int a;
    for(a=0;x>0;a++){
        x/=10;
    }
return a;
}
int he(int x,int y){
     int a,t;
     for(a=1,t=0;y>0;a*=10,y--){
        t+=x/a%10;
     }
     return t;
}
int main()
{
    int n,i;
    scanf("%d",&n);
    for(i=0;n>0;i++){
        n=n-he(n,wei(n));
    }
    printf("%d",i);
    return 0;
}

he是和的拼音()

12.分数的加减乘除法

#include<stdio.h>
#include<math.h>
int gcd(int x,int y){
    if(y)
        return gcd(y,x%y);
    else return x;
}
int main()
{
    int a,b,c,d;
    scanf("%d/%d %d/%d",&a,&b,&c,&d);
    printf("(%d/%d)+(%d/%d)=%d/%d\n",a,b,c,d,(a*d+b*c)/gcd(a*d+b*c,b*d),b*d/gcd(a*d+b*c,b*d));
    printf("(%d/%d)-(%d/%d)=%d/%d\n",a,b,c,d,(a*d-b*c)/gcd(a*d-b*c,b*d),b*d/gcd(a*d-b*c,b*d));
    printf("(%d/%d)*(%d/%d)=%d/%d\n",a,b,c,d,a*c/gcd(a*c,b*d),b*d/gcd(a*c,b*d));
    printf("(%d/%d)/(%d/%d)=%d/%d\n",a,b,c,d,(a*d)/gcd(a*d,b*c),b*c/gcd(a*d,b*c));

    return 0;
}

这道题用到了求最大公约数(欧几里得算法)

13.级数和

#include<stdio.h>
double sum(double n)
{
    double t,d,s;
    for(t=1;t<n;t++)
   {if(t+1<10)d=(t+1)/10;
           else d=(t+1)/100;
        printf("%g+",d+t);
    s+=t+d;
   }
   if (t+1==100)d=0.1,printf("%g",d+t);
   else if(t+1<10)d=(t+1)/10,printf("%g",d+t);
   else d=(t+1)/100,printf("%g",d+t);
   s+=t+d;
   return s;
}
int main()
{
    double n;
    scanf("%lf",&n);
    printf("=%g",sum(n));
}

这里我把最后一位分开进行判断是因为我原本在倒数第二行“=%g”前边用了退格符,把多余的一个加号去掉,它报错了我就分开打了。

14.倍数和

#include<stdio.h>
int main()
{
    int T,i,sum,d;
    scanf("%d",&T);
    int A[T];
    for(i=0;i<=T-1;i++){
        scanf("%d",&A[i]);
        }
    for(i=0;i<=T-1;i++){
    for(sum=0,d=1;d<A[i];d++){

            if(d%3==0||d%5==0)sum+=d;
    }

        printf("%d\n",sum);
    }
    return 0;
}

这道题一开始完全不会做,是看了去年学长的文章才知道要用数组的。
没有获得授权就不转了。
见文章https://blog.csdn.net/2302_80002065/article/details/135132048

15.组合数

#include<stdio.h>
int pair(int n)
{
    int a,b,c,d,i=0;
    for(a=0;a<=9;a++)
        for(b=0;b<=9;b++)
            for(c=0;c<=9;c++)
                for(d=0;d<=9;d++){
                    if(a+b+c+d==n)i++;

                }
    printf("%d",i);
}
int main()
{
    int n;
    scanf("%d",&n);
    pair(n);
    return 0;
}

16.幂数模

#include<stdio.h>
int main()
{
    long long unsigned a,b,c,d=1;
    scanf("%llu%llu%llu",&a,&b,&c);
    //a=a%c;
    while(b!=0){
        if(b%2==1)d=(d*a)%c;
        b/=2;
        a=(a*a)%c;
    }
    printf("%llu",d);
    return 0;
}

用到快速幂以及取模(求余)。
有个同学是在我代码注释部分加上了这个,理论是没错,但是noj报WA,我放去洛谷AC了,怪怪的。

17.比率

#include<stdio.h>
int gcd(int x,int y)
{
    if(y)return gcd(y,x%y);
    else return x;

}
int main()
{
    double a,n=1;
    int d;
    scanf("%lf",&a);
    double t=a;
    d=(int)a;
    while(d!=t){
        n*=10;
        t=n*a;
        d=(int)t;
    }
    int b=(int)n;
    printf("%d/%d",d/gcd(d,b),b/gcd(d,b));
    return 0;
}

补:从大佬那里学到可以用floor()取整,就不用(int)强行取整了

18.乘数模

#include<stdio.h>
int main()
{
    long long unsigned a,b,m;
    scanf("%llu%llu%llu",&a,&b,&m);
    printf("%llu",((a%m)*(b%m)%m));
    return 0;
}

在前面做幂数模的时候看了取模的运算法则做这道题就会简单。

19.方阵

#include<stdio.h>
int main()
{
    int n,t;
    scanf("%d",&n);
    for(t=1;t<=n;t++)
    {
        int p;
        for(p=1;p<=n;p++)
        {
            if(t>=p)printf("%d ",t-p);
            else printf("%d ",p-t);
        }
        printf("\n");
    }
    return 0;
}

20.对称数

#include<stdio.h>
int wei(int x)
{
    int a;
    for(a=0;x>0;a++)
    {
        x/=10;
    }
    return a;

}
int main()
{
    int a,m,count;
    scanf("%d",&a);
    int n=wei(a);
    int A[n];
    for(m=1,count=0;count<=n-1;count++,m*=10)
    {
        A[count]=a/m%10;
    }
    for(count=0;count<=n-1;count++)
    {
            if((A[count]==1&&A[n-1-count]==1||A[count]==8&&A[n-1-count]==8||A[count]==0&&A[n-1-count]==0||A[count]==9&&A[n-1-count]==6||A[count]==6||A[n-1-count]==9)==0)
            {
                printf("No");
                break;
            }
    }
    if(count==n)printf("Yes");
    return 0;

呃呃,应该是转180吧,转360做什么。
这里我选择用数组把各个位数录进去,然后进行判断。

21-30枚举

21.竖式乘法

#include<stdio.h>
int wei(int n)
{
    int i;
    if(n==0)return 1;
    for(i=0;n>0;i++)
        n/=10;
    return i;
}
void load(int A[],int a)
{
    int i=wei(a),t;
    int m;
    for(m=1,t=i;i>0;i--){
        A[t-i]=a/m%10;
        m*=10;
    }
}
int main()
{
    int n,A[100],b,numtotal;
    scanf("%d%d",&b,&n);
    numtotal=wei(b*n)+1;
    int numn=wei(n),numb=wei(b);
    load(A,n);
    int t,i,p=0;
    for(t=0;t<numn;t++){
        A[t]=A[t]*b;
    }
    for(t=0;numtotal-numb-t>0;t++)printf(" ");
    printf("%d\nx",b);
    for(t=1;numtotal-numn-t>0;t++)printf(" ");
    printf("%d\n",n);
    for(t=0;numtotal-t>0;t++)printf("-");
    printf("\n");
    for(t=0;t<numn;t++){
        if(t==numn-1)p++,printf("+");
        for(i=0;numtotal-i-t-p-wei(A[t])>0;i++)printf(" ");
            printf("%d\n",A[t]);
    }
    for(t=0;numtotal-t>0;t++)printf("-");
    printf("\n %d",b*n);
    return 0;
}

裹脚布,麻
不过很多部分是重复的,搞清楚核心其实还好

22.俄罗斯农夫乘法

#include<stdio.h>
int main()
{
    int a,b,sum=0;
    scanf("%d%d",&a,&b);
    if(a==0||b==0);
    else if(a==1)sum=a*b;
    else   {printf("%d %d\n",a,b);
        if(a%2==1)sum=b;
        while(a!=1){
        a/=2;
        b*=2;
        if(a%2==1)sum+=b;
        printf("%d %d\n",a,b);
    }
    }
    printf("%d",sum);
    return 0;
}

23.方案数

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

这道题我没有从原理出发,推荐看学长们的。

24.好数字

#include<stdio.h>
#include<math.h>
int main()
{
    long long N,cnt,m;
    m=(long long)(pow(10,9)+7);
    scanf("%lld",&N);
    N--;
    for(cnt=1;N>-1;N--){
        if(N%2==0)cnt=(cnt*5)%m;
        else cnt=(cnt*4)%m;
    }
    printf("%llu",cnt);
    return 0;
}

这个10的九次方+7你用define去定义也行,用1e9+7也好,省时间了

25.阶乘倍数

#include<stdio.h>
#include<stdbool.h>
#include<math.h>
bool isPrime(long long n)
{
    if(n<=3)return n>1;
    if(n%6!=1&&n%6!=5)return false;
    int m=(long long)sqrt(n);
    for(int i=5;i<=m;i+=6){
        if(n%i==0||n%(i+2)==0){
            return false;
        }
    }
    return true;
}
int main()
{
    long long K,N=1,t,mul;
    scanf("%lld",&K);
    if(isPrime(K))N=K;
    else while(K){
        for(t=N,mul=1;t>0;t--)mul*=t;
        if(mul%K==0)break;
        N++;
    }
    printf("%lld",N);
    return 0;
}

判断是否为质数(素数),是的话直接输出K;简单的循环会溢出;
然后在https://blog.csdn.net/annesede/article/details/133761873这位佬的文章中,他是分解质因数,然后二分查找,解析见文章首的链接;

26.毕达哥拉斯三元组

#include<stdio.h>
int main()
{
    unsigned a,b,c,n;
    scanf("%u",&n);
    for(a=1;a<n/3;a++){
        for(c=n-1;c>n/3;c--){
               b=n-a-c;
        if(a*a+b*b==c*c&&b<c){
            printf("%llu",a*b*c);
            break;
           }
        }
    }
return 0;
}

a的范围实际可以精确到n/4,b是n/2;运算时间可以少一半

27.最大数字

#include<stdio.h>
#include<stdbool.h>
bool isNonDecr(unsigned N)
{
    unsigned predigit=N%10;
    while(N){
            unsigned digit=N/10%10;
        if(digit>predigit){
                return false;
        }
        predigit=digit;
        N/=10;
    }
    return true;
}
int main()
{
    unsigned N;
    scanf("%u",&N);
    while(!isNonDecr(N)){
        --N;
    }
    printf("%u",N);
    return 0;
}

进行每一个位数的判断,若不是递增即N–,注意isNonDecr前有“!”
可直接各个位数比较便不必将N各个位数放入数组中。
补:可从高位开始检测,发现在第i位存在递减时,将该位数值建议,其后各位均改成9,代码见下

#include<stdio.h>
#include<math.h>
typedef unsigned long long uint64;
int wei(uint64 N)
{
    int a;
    for(a=1;N>0;a++)
        N/=10;
    return a;
}
uint64 isNonDecr(uint64 N)
{
    int t;
    for(t=wei(N)-1;t>0;t--){
            int m=N/(uint64)pow(10,t)%10;
        int n=N/(uint64)pow(10,t-1)%10;
        if(m>n)return (N/(uint64)pow(10,t)*(uint64)pow(10,t))-1;
    }
    return N;
}
int main()
{
    uint64  N;
    scanf("%llu",&N);
    printf("%llu",isNonDecr(N));
    return 0;
}

28.查找数列

#include<stdio.h>
int main()
{
    int n,a,i;
    scanf("%d",&n);
    for(a=n*2,i=1;;i++){
            if(a>=i*(i+1)&&a<(i+1)*(i+2))break;
    }
    a=n-(i*(i+1))/2;
    printf("%d",a);
    return 0;
}

29.倒水

#include<stdio.h>
struct volume{
  int m,n;
}A[10000];//A.m记录m当前水量,A.n记录n当前水量。
int vis[1000][1000];//记录vis[m当前水量][n当前水量]出现时的最小操作次数
//后续有再出现必定比最小的大(我在说什么),因此会重复行走,就不必进行下去了
void bfs(int m,int n,int d)
{
    A[1].m=0,A[1].n=0;
    int a=0,b=0;
    int T,front=1,rear=1;
    vis[a][b]=1;
    while(front<=rear){
        a=A[front].m;
        b=A[front].n;
        T=vis[a][b];
        if(a==d||b==d){
            printf("%d",T-1);
            break;
        }
        //pour
        if(a&&!vis[0][b]){
            vis[0][b]=T+1;
            A[++rear].m=0;
            A[rear].n=b;
        }
        if(b&&!vis[a][0]){
            vis[a][0]=T+1;
            A[++rear].m=a;
            A[rear].n=0;
        }
        //fill
        if(a<m&&!vis[m][b]){
            vis[m][b]=T+1;
            A[++rear].m=m;
            A[rear].n=b;
        }
        if(b<n&&!vis[a][n]){
            vis[a][n]=T+1;
            A[++rear].m=a;
            A[rear].n=n;
        }
        //trans
        //a->b
        if(a+b<=n&&!vis[0][a+b]){
            vis[0][a+b]=T+1;
            A[++rear].m=0;
            A[rear].n=a+b;
        }
        if(a+b>n&&!vis[a+b-n][n]){
            vis[a+b-n][n]=T+1;
            A[++rear].m=a+b-n;
            A[rear].n=n;
        }
        //b->a
        if(a+b<=m&&!vis[a+b][0]){
            vis[a+b][0]=T+1;
            A[++rear].m=a+b;
            A[rear].n=0;
        }
        if(a+b>m&&!vis[m][a+b-m]){
            vis[m][a+b-m]=T+1;
            A[++rear].m=m;
            A[rear].n=a+b-m;
        }
        front++;
    }
}

int main()
{
    int m,n,d;
    scanf("%d%d%d",&m,&n,&d);
    bfs(m,n,d);
    return 0;
}

要用BFS(宽度优先搜索),你体会到姜的良苦用心了嘛?
哥们是真不会做,学去吧。我这里的话是用vis的数组记录操作次数T,以保证每次出队时T能够对应上;
然后我个人理解,宽度优先搜索就是一个不断入队出队(队列)的过程,在过程中寻找目标结点。
在出队后对该结点进行拓展,并判断拓展出的节点是否符合目标结点要求**/**在拓展时就进行判断(我这里怕他占用时间就没弄,感觉如果是一个结点就可以拓展出非常多新的结点的话,在拓展时就判断更优,转到正确的道路时不知道得多久了hh)
对了,切记如果你的front初始值是0,那么bfs结束条件是front<rear。初始值是1,那么结束条件就是front<=rear.

30.余数和

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

呃呃,没想到三十题是这个,有种风雨后见彩虹的感觉hh

31-40函数

31.佩尔数

#include<stdio.h>
#define unit64 unsigned long long
unit64 PA(unit64 n)
{
    if(n==0)return 0;
    else if(n==1)return 1;
    return 2*PA(n-1)+PA(n-2);

}
unit64 PB(unit64 n)
{
    unit64 p0=0,p1=1,pn,i;
    for(i=0;i<=n;i++)
        if(i==0)pn=p0;
        else if(i==1)pn=p1;
        else{
            pn=2*p1+p0;
            p0=p1;
            p1=pn;
        }
    return pn;
}
int main()
{
    unit64 n,pn;
    scanf("%llu",&n);
    if(n==0)pn=0;
    else if(n%2==0)pn=PB(n);
    else pn=PA(n);
    printf("%llu",pn);
    return 0;
}

32.基思数

#include<stdio.h>
#include<math.h>
int A[8];
int wei(int N)
{
    int i=0,j=N;
    while(j){
        j/=10;
        i++;
    }
    int k=(int)pow(10,i-1);
    for(j=0;j<i;j++){
        A[j]=N/k%10;
        k/=10;
    }
    return i;
}
int isKeith(int N)
{
    int i=wei(N),sum=0,j;
    while(N>sum){
        for(j=0,sum=0;j<i;j++){
            sum+=A[j];
        A[j]=A[j+1];
     if(j==i-1)A[j]=sum;
        }
        if(N==sum){
            printf("Yes");
            return 1;
        }
    }
    printf("No");
    return 0;
}
int main()
{
    int N;
    scanf("%d",&N);
    isKeith(N);
    return 0;
}

33.二进制表示

#include<stdio.h>
void binary(int n)
{
    int i,pos=0;
    for(i=15;i>=0;--i){
        if((n>>i)%2==1){
            if(pos)printf("+");
            if(i>=2){
                printf("2(");
                binary(i);
                printf(")");
            }
            if(i==1)
                printf("2");
            if(i==0)
                printf("2(0)");
            pos=1;
        }
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    binary(n);
    return 0;
}

注意在i>=2时要进一步拆分,拿递归做简洁些。

34.冰雹数列

#include<stdio.h>
int func(int n)
{
    if(n%2==0)return n/2;
    else return 3*n+1;
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n!=1){
        printf("%d ",n);
        n=func(n);
    }
    printf("1");
    return 0;
}

35.可变参数累加

#include<stdio.h>
#include<stdarg.h>
int sum(int first,...)
{
    va_list p;
    va_start(p,first);
    int sum=0,i=first;
    while(i){
        sum+=i;
        i=va_arg(p,int);
    }
    va_end(p);
    return sum;
}
int main()
{
    int a,b,c,d,e,f;
    scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
    printf("%d",sum(a,b,0)-sum(c,d,e,f,0));
    return 0;
}

36.素数

#include<stdio.h>
#include<stdbool.h>
void PrimeNum(int a,int b);
bool isPrime(int n);
void PrimeNum(int a,int b)
{
    int num=0,n;
    for(n=5;n<a;n+=6);
    if(a<=3){
        for(int m=3;m>=a;m--)
            num++;
    }
    for(;n<=b&&n+2<=b;n+=6){
        if(isPrime(n))++num;
        if(isPrime(n+2))++num;
    }
    if(n<=b&&n+2>b)
        if(isPrime(n))++num;
    printf("%d",num);
}
bool isPrime(int n)
{
    if(n==2||n==3||n==5)return true;
    else if(n%2==0||n%3==0)return false;
    for(int a=5;a*a<=n;a+=6){
        if(n%a==0||n%(a+2)==0)return false;
    }
    return true;
}
int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    PrimeNum(a,b);
    return 0;
}//480ms

这个地方的a*a<=n;推荐写成a<=n/a,避免溢出;
优解哥们还在学
Eratosthense筛见下。

#include<stdio.h>
#include<stdbool.h>
#include<math.h>
int eratosthense(int a,int b)
{
    int range=b-a+1,start,i,j;
    bool FLAG[range];
    for(i=0;i<range;i++)
        FLAG[i]=true;

    for(i=2;i<=sqrt(b);i++){
        start=a/i*i;
        if(start<a)start+=i;
        if(start==i)start+=i;
        for(j=start;j<=b;j+=i){
            if(FLAG[j-a])
                FLAG[j-a]=false;
        }
    }
    for(i=0,j=0;i<range;i++){
        if(FLAG[i])j++;
    }
    return j;
}
int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    if(a<2)a=2;
    int ans=eratosthense(a,b);
    printf("%d",ans);
    return 0;
}//87ms

37.运动会

#include<stdio.h>
#include<stdbool.h>
#include<string.h>
int phi[40001],cnt;
bool isPrime[40001];
int Prime[40001];
int sum[40001];
void Getphi()
{
    memset(isPrime,1,sizeof(isPrime));
    isPrime[1]=0;
    phi[1]=0;

    for(int i=2;i<=40000;i++){
        if(isPrime[i]){
            Prime[++cnt]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=cnt&&i*Prime[j]<=40000;j++){

             isPrime[i*Prime[j]]=0;
        if(i%Prime[j]==0){
            phi[i*Prime[j]]=Prime[j]*phi[i];
            break;
        }
        else phi[i*Prime[j]]=phi[i]*phi[Prime[j]];
    }
}
}
int main()
{
    int n;
    scanf("%d",&n);
    Getphi();
    sum[1]=1;
    for(int i=2;i<=n-1;i++)
    {
        sum[i]=sum[i-1]+phi[i];
        //printf("%d\n",sum[i]);
    }
    if(n==1)printf("0");
    else printf("%d\n",2*sum[n-1]+1);
    return 0;
}

欧拉函数。
在这里插入图片描述
我们将队长作为原点建立直角坐标系。队员们的坐标即为(x,y)
遮挡,即意味着该直线上已有一点。
若未被遮挡,即可看见,此时gcd(x,y)=1(若为2x,2y,斜率是和x,y相同,但是x,y数字小,应当先出现对吧),也就是x,y互质。
因为下半区域三角形与上半区域三角形对称,我们只要算下半部分即可。
当横坐标为x时,该竖列也有x个人,刚好就是求小于等于x且与x互质的数的个数。这就是欧拉函数所解决的问题,计算完欧拉函数后,结果应为各个横坐标欧拉数的sum*2+1,为什么加1呢,因为上图红线上有一个人没有算上。
解决啦。
(然后这个地方刨去计算phi,其实就是欧拉筛,时间复杂度比上一题的埃氏筛更小)

38.哈沙德数

#include<stdio.h>
int HarshadNumber(int n)
{
    int t=n,s=0;
    while(t){
        s=s+t%10;
        t=t/10;
    }
    if(s&&n%s==0)return n/s;
    return 0;
}
int main()
{
    int n,a,cnt=0;
    scanf("%d",&n);
    a=n;
    while(HarshadNumber(a)){
        a=HarshadNumber(a);
        ++cnt;
        if(a==1)break;
    }
    printf("%d",cnt);
    return 0;
}

39.可变参数平均

#include<stdio.h>
#include<stdarg.h>

double avg(double first,...)
{
    va_list p;
    double sum=0,i=first;
    va_start(p,first);
    while(i--){
        sum+=va_arg(p,double);
    }
    return sum/first;
}
int main()
{
    double a,b,c,d,e;
    scanf("%lf %lf %lf %lf %lf",&a,&b,&c,&d,&e);
    double ans=avg(2,a,b)-avg(3,c,d,e);
    printf("%.4lf",ans);
    return 0;
}

40.光线追踪

#include<stdio.h>
int flag;
unsigned getlength(unsigned n,unsigned x)
{
    unsigned len,a,b;
    len=0;
    if(flag){
        a=n,b=x;
    }
    else a=n-x,b=x;
    if(b<=a){
        if(a%b==0)len+=b*((2*(a/b))-1);
    else {
            len+=b*2*(a/b);
            int c=a-(a/b*b);
            ++flag;
            len+=getlength(b,c);
        }
    }
    return len;
}
int main()
{
    unsigned n,x;
    scanf("%u %u",&n,&x);
    unsigned i=n+getlength(n,x);
    printf("%u",i);
    return 0;
}

41-49数组

41.货运优化

#include<stdio.h>
int main()
{
    int A[6];
    int M[4]={0,5,3,1};
    while(1){
        for(int j=0;j<6;j++)
            scanf("%d",&A[j]);
        if(A[0]+A[1]+A[2]+A[3]+A[4]+A[5]==0)break;
        int num=0,m,n1,r;
        num+=A[5]+A[4]+A[3]+(A[2]+3)/4;
        m=A[2]%4;
        m=M[m];
        n1=A[3]*5+m;
        if(A[1]>n1)num+=(A[1]+8)/9;
        r=36*num-(A[5]*36+A[4]*25+A[3]*16+A[2]*9+A[1]*4);
        if(A[0]>r)num+=(A[0]+35)/36;
        printf("%d\n",num);
    }

    return 0;
}

二维数组过不了,莫名其妙

42.航空旅行

#include<stdio.h>
int main()
{
    int t,a,b,c,d,e;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);
        if(a+b+c>c+d)printf("NO\n");
        else {
            if((a+b<=d&&c<=e)||(a+c<=d&&b<=e)||(b+c<=d&&a<=e)){
                printf("YES\n");
            }
            else printf("NO\n");
        }
    }
    return 0;
}

43.飞机起飞速度(WA)

他们说有问题我就还没做,先处理别的。

44.素数筛选法

#include<stdio.h>
#include<string.h>
int Prime[10000001];
int isPrime[10000001];
void euler(int n)
{
    int cnt=0;

    memset(isPrime,1,n*4);

    isPrime[1]=0;
    for(int i=2;i<=n;i++){
        if(isPrime[i]){
            Prime[++cnt]=i;
        }
        for(int j=1;j<=cnt&&Prime[j]*i<=n;j++){
            isPrime[i*Prime[j]]=0;
            if(i%Prime[j]==0){
                break;
            }
        }
    }
    printf("%d\n",cnt);

}
int main()
{
    int n;
    scanf("%d",&n);
    euler(n);
    return 0;
}

明明前面就用了埃氏筛和欧拉筛了,现在才出这种题目,莫名其妙

45.回文数之和

#include<stdio.h>
#include<stdbool.h>

bool Double(int i,int k)
{
    int A[33];//m的类型是int形,2进制不会超过32位,更高的进制亦然
    int a=i,cnt=0;
    while(a){
       A[++cnt]=a%10;
       a/=10;
    }
    for(int f=1;f<=cnt;f++,cnt--){
        if(A[f]!=A[cnt])return false;
    }//判断十进制

    //判断k进制
    cnt=0;
    while(i){
        A[++cnt]=i%k;
        i/=k;
    }
    for(int f=1;f<=cnt;f++,cnt--){
        if(A[f]!=A[cnt])return false;
    }
    return true;
}
int main()
{
    int n,k,sum=0;
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++){
        if(Double(i,k))sum+=i;
    }
    printf("%d",sum);
    return 0;
}

46.波士顿房价预测(简单线性回归)

#include<stdio.h>
#include<math.h>
double X[1001];
double Y[1001];
int main()
{
    int n;
    double k,b,xa=0,ya=0,above=0,under=0;

    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lf %lf",&X[i],&Y[i]);
    }
    for(int i=1;i<=n;i++){
        xa+=X[i]/n;
        ya+=Y[i]/n;
    }
    for(int i=1;i<=n;i++){
        above+=(X[i]-xa)*(Y[i]-ya);
        under+=pow((X[i]-xa),2);
    }
    k=above/under;
    b=ya-k*xa;
    printf("Y=%.4lf+%.4lf*X",b,k);
    return 0;
}

47.完美矩阵

#include<stdio.h>
#include<math.h>
#include<stdbool.h>
int A[301][301];//从1开始录入
bool isperfect(int a,int n,int b,int m)
{
    int i,j,subsum=0;
    for(i=a;i<=n;i++){
        for(j=b;j<=m;j++){
            if(i==a||i==n||j==b||j==m){//外
                if(A[i][j]!=1)return false;
            }
            else{//内
                subsum+=A[i][j];
            }
        }
    }
    if(fabs(subsum)>1)return false;//判
    else return true;
}
void perfect(int n,int m)
{
    int ans=0,i,j,k;
    int min=fmin(n,m);
    for(k=2;k<=min;k++){
        for(i=1;i<=n-k+1;i++){//所处行
            for(j=1;j<=m-k+1;j++){//所处列
                if(k==2){
                    if(A[i][j]==1&&A[i+1][j]==1&&A[i][j+1]==1&&A[i+1][j+1]==1)
                        ++ans;
                }
                else if(isperfect(i,i+k-1,j,j+k-1))++ans;
            }
        }
    }
    printf("%d",ans);
}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            scanf("%d",&A[i][j]);
            if(A[i][j]==0)A[i][j]=-1;//便于subsum的记数
        }
    perfect(n,m);
    return 0;
}

搞半天发现子矩阵只能是方阵,题目描述怪怪的。

48.稀疏矩阵

#include<stdio.h>
#define MAX 101
#define STANDARD 5e-2
int a[MAX][MAX];
int main()
{
    double n,m,cnt=0;
    scanf("%lf %lf",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
            if(a[i][j]!=0)cnt++;
        }
    double temp=cnt/(n*m);
    if(temp<=STANDARD||cnt==n||cnt==m)printf("Yes\n");
    else printf("No");
    return 0;
}

两个百科符合一个就可以

49.蒙特卡罗方法求积分

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

double func1(double x)
{
    return pow(x,4)*exp(-x);
}
double func2(double x)
{
    return pow(x,2)+1;
}
double func3(double x)
{
    return cos(x);
}
double func4(double x)
{
    return sqrt(x)*(x-2);
}
double func5(double x)
{
    return 2*sin(x)-5*cos(x);
}

double func(int m,double x)
{
    switch(m){
    case 1:return func1(x);
    case 2:return func2(x);
    case 3:return func3(x);
    case 4:return func4(x);
    case 5:return func5(x);
    }
}
int main()
{
    int m,n;
    double a,b,fsum=0,x,ans;
    srand(RAND_MAX);

    scanf("%d %lf %lf %d",&m,&a,&b,&n);
    for(int i=1;i<n;i++){
        x=a+(b-a)*rand()/(double)RAND_MAX;
        fsum+=func(m,x);
    }
    ans=(b-a)/n*fsum;
    printf("%.6lf",ans);
    return 0;
}

在这里插入图片描述
公式给的这个,样本是N个,但是取值的时候得是N-1个样本才AC,呃呃;

50.行列式值

#include<stdio.h>
#define MAX 10

void swaprows(double matrix[][MAX],int row1,int row2,int n)
{
    for(int i=0;i<n;i++){
        double temp=matrix[row1][i];
        matrix[row1][i]=matrix[row2][i];
        matrix[row2][i]=temp;
    }
}
double caldeterminant(double matrix[][MAX],int n)
{
    double ans=1.0,sgn=1.0;
    int i,j,k;

    for(i=0;i<n;i++){
        if(matrix[i][i]==0.0){
            for(j=i+1;j<n;j++){
                if(matrix[j][i]!=0.0){
                    swaprows(matrix,i,j,n);
                    sgn*=-1.0;
                    break;
                }
            }
        }

        if(matrix[i][i]==0)
            return 0;

        double pivot=matrix[i][i];
        ans*=pivot;

        for(j=i;j<n;j++)
            matrix[i][j]/=pivot;

        for(j=i+1;j<n;j++){
            double factor=matrix[j][i];
            for(k=i;k<n;k++){
                matrix[j][k]-=factor*matrix[i][k];
            }
        }
    }
    return ans*sgn;
}

int main()
{
    int n;
    scanf("%d",&n);
    double matrix[MAX][MAX];
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            scanf("%lf",&matrix[i][j]);
    double determinant=caldeterminant(matrix,n);
    printf("%.0lf",determinant);
    return 0;
}

被强迫学习线代了,基本上是照着大佬的代码去抄的,把输入的行列式化成上三角然后求行列式值即可。

51-60字符串

51.字符串后缀

#include<stdio.h>
#include<string.h>
#define LEN 1000

int str_endswitch(char str[],char suffix[])
{
    int len2=strlen(suffix),len1=strlen(str);
    char judge[len2+1];
    strcpy(judge,str+(len1-len2));
    return strcmp(suffix,judge);
}
int main()
{
    char str[LEN],suffix[LEN];
    fgets(str,LEN,stdin);
    fgets(suffix,LEN,stdin);
    str[strcspn(str, "\n")] = 0;
    suffix[strcspn(suffix, "\n")] = 0;
    /*scanf("%[^\n]",str);
      scanf("%[^\n]",suffix);
    */
    if(str_endswitch(str,suffix)==0){
        printf("Yes\n");
    }
    else printf("No\n");
    return 0;
}

[^\n]好啊,都不用去换行符了。

52.前后缀移除

#include<stdio.h>
#include<string.h>
#define LEN 1000

int str_lstrip(char str[],char chars[])
{
    int cnt=0;
    char *p=str;
    while(strchr(chars,*p)){
        p++;
        cnt++;
    }
    puts(p);
    return cnt;
}

int str_rstrip(char str[],char chars[])
{
    int cnt=0;
    char *p=str+strlen(str)-1,temp[LEN]="";
    while(strchr(chars,*p)){
        p--;
        cnt++;
    }
    strncat(temp,str,strlen(str)-cnt);
    puts(temp);
    return strlen(str)-cnt;
}

int main()
{
    int cnt1,cnt2;
    char str[LEN],chars[LEN],temp[LEN]="";

    scanf("%[^\n] %[^\n]",str,chars);
    //printf("%u %u",strlen(str),strlen(chars));
    //puts(str),puts(chars);
    cnt1=str_lstrip(str,chars);
    cnt2=str_rstrip(str,chars);

    strncat(temp,str,cnt2);
    strcpy(str,temp+cnt1);
    puts(str);
    return 0;
}

佬用的是memmove,直接把str在调用函数里改了。

53.字符串切片

#include<stdio.h>
#include<string.h>
#define STLEN 1000

int main()
{
    char src[STLEN];
    int times,n,len;
    scanf("%[^\n] %d",src,&times);
    len=strlen(src);
    while(times--){
        int start,stop=len,step=1,*p[3]={&start,&stop,&step};
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",p[i]);
            if(*p[i]<0){
                if(i==2){
                    ;
                }
                else{
                     *p[i]+=len;
                }
            }
        }
        if(start<stop) for(;start<stop;start+=step){
            printf("%c",src[start]);
        }
        else for(;start>stop;start+=step){
            printf("%c",src[start]);
        }
        printf("\n");
    }
    return 0;
}

54.Atol转换

#include<stdio.h>
#include<limits.h>
#define STLEN 1000

int Atol(char str[])
{
    int sgn=1,flag=1;
    long long ans=0;
    char *p=str;
    while(*p){
        if(*p==' '&&flag);
        else if((*p=='-'||*p=='+')&&flag){
            if(*p=='-'){
                sgn*=-1;
            }
            flag=0;
        }
        else if(*p<='9'&&*p>='0'){
                flag=0;
                ans=ans*10+(*p-'0');
            if((ans*sgn)>=INT_MAX){
                return INT_MAX;
            }
            else if((ans*sgn)<=INT_MIN){
                return INT_MAX;
            }
        }
        else break;
        p++;
    }
    return sgn*ans;
}
int main()
{
    char str[STLEN];
    scanf("%[^\n]",str);
    int ans=Atol(str);
    printf("%d",ans);
    return 0;
}

用limits库里面的INT_MAX和INT_MIN去限制范围。

55.元宇宙

#include<stdio.h>
#include<string.h>
#define STLEN 12

char INDEX[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int trans(char i)
{
    if(i<='9')return i-'0';
    else return i-'A'+10;
}

void sum36(char a[],char b[])
{
    int lena=strlen(a),lenb=strlen(b),big,next=0,temp;
    int A[STLEN],B[STLEN],seq[STLEN],i;
    char ANS[STLEN]="";

    memset(A,0,sizeof(A));
    memset(B,0,sizeof(B));
    memset(seq,0,sizeof(seq));
    
    for(i=0;i<lena;i++)A[i]=trans(a[lena-i-1]);
    for(i=0;i<lenb;i++)B[i]=trans(b[lenb-i-1]);
    
    big=lena>lenb?lena:lenb;
    for(i=0;i<big;i++){
        temp=A[i]+B[i]+next;
        if(temp>=36){
            next=1;
            temp%=36;
        }
        else next=0;
        seq[i]=temp;
    }
    if(next)seq[i]+=1;
    
    int lenANS=big+next;
    for(int i=0;i<lenANS;i++){
        ANS[i]=INDEX[seq[lenANS-i-1]];
    }
    ANS[lenANS]='\0';
    puts(ANS);
}

int main()
{
    char a[STLEN]="",b[STLEN]="";

    scanf("%s %s",a,b);
    sum36(a,b);
    return 0;
}

56.大小写交换

#include<stdio.h>
#define STLEN 1000
#include<string.h>

void str_swapcase(char str[])
{
    int len=strlen(str);
    for(int i=0;i<len;i++){
        if(str[i]>='a'&&str[i]<='z'){
            str[i]-=32;
        }
        else if(str[i]>='A'&&str[i]<='Z'){
            str[i]+=32;
        }//用else if 避免将小写变成大写后又变回小写
    }
    puts(str);
}

int main()
{
    char str[STLEN];
    scanf("%[^\n]",str);
    str_swapcase(str);
    return 0;
}

57.字符串替换(WA)

同飞机起飞,不处理先。

58.分离字符串

#include<stdio.h>
#define STLEN 2000
#include<string.h>
char sarr[20][100];
int i=-1;
void str_split(char *str,char *sep)
{
    int len=strlen(sep);
    char *p=strstr(str,sep);
    if(p){
        strncpy(sarr[++i],str,p-str);
        //puts(sarr[i]);
        str_split(p+len,sep);
    }
    else {
        strcpy(sarr[++i],str);
        //puts(sarr[i]);
    }
}


int main()
{
    char str[STLEN]="",sep[STLEN]="";
    scanf("%[^\n] %[^\n]",str,sep);
    str_split(str,sep);
    for(int j=0;j<=i;j++){
        puts(sarr[j]);
    }
    return 0;
}

59.Kids A+B

#include <stdio.h>
#include <string.h>
 
char ans[30] = "";
 
int strToNum(char *str) {
    if(strstr(str, "zero")) return 0;
    if(strstr(str, "ten")) return 10;
    if(strstr(str, "eleven")) return 11;
    if(strstr(str, "twelve")) return 12;
    if(strstr(str, "thirteen")) return 13;
    if(strstr(str, "fourteen")) return 14;
    if(strstr(str, "fifteen")) return 15;
    if(strstr(str, "sixteen")) return 16;
    if(strstr(str, "seventeen")) return 17;
    if(strstr(str, "eighteen")) return 18;
    if(strstr(str, "nineteen")) return 19;
 
    int unit = 0, decade = 0;
    if(strstr(str, "one")) unit = 1;
    if(strstr(str, "two")) unit = 2;
    if(strstr(str, "three")) unit = 3;
    if(strstr(str, "four")) unit = 4;
    if(strstr(str, "five")) unit = 5;
    if(strstr(str, "six")) unit = 6;
    if(strstr(str, "seven")) unit = 7;
    if(strstr(str, "eight")) unit = 8;
    if(strstr(str, "nine")) unit = 9;
    if(strstr(str, "twenty")) decade = 20;
    if(strstr(str, "thirty")) decade = 30;
    if(strstr(str, "forty")) decade = 40;
    if(strstr(str, "fifty")) decade = 50;
    if(strstr(str, "sixty")) decade = 60;
    if(strstr(str, "seventy")) decade = 70;
    if(strstr(str, "eighty")) decade = 80;
    if(strstr(str, "ninety")) decade = 90;
    return unit + decade;
}
 
void numToStr(int n) {
    switch (n) {
        case 0: {
            strcpy(ans, "zero");
            char *p = ans;
            return;
        }
        case 11: {
            strcpy(ans, "eleven");
            char *p = ans;
            return;
        }
        case 12: {
            strcpy(ans, "twelve");
            char *p = ans;
            return;
        }
        case 13: {
            strcpy(ans, "thirteen");
            char *p = ans;
            return;
        }
        case 14: {
            strcpy(ans, "fourteen");
            char *p = ans;
            return;
        }
        case 15: {
            strcpy(ans, "fifteen");
            char *p = ans;
            return;
        }
        case 16: {
            strcpy(ans, "sixteen");
            char *p = ans;
            return;
        }
        case 17: {
            strcpy(ans, "seventeen");
            char *p = ans;
            return;
        }
        case 18: {
            strcpy(ans, "eighteen");
            char *p = ans;
            return;
        }
        case 19: {
            strcpy(ans, "nineteen");
            char *p = ans;
            return;
        }
        default:
            break;
    }
 
    int decade = (n / 10) % 10, unit = n % 10;
    switch (decade) {
        case 2: {
            strcpy(ans, "twenty");
            break;
        }
        case 3: {
            strcpy(ans, "thirty");
            break;
        }
        case 4: {
            strcpy(ans, "forty");
            break;
        }
        case 5: {
            strcpy(ans, "fifty");
            break;
        }
        case 6: {
            strcpy(ans, "sixty");
            break;
        }
        case 7: {
            strcpy(ans, "seventy");
            break;
        }
        case 8: {
            strcpy(ans, "eighty");
            break;
        }
        case 9: {
            strcpy(ans, "ninety");
            break;
        }
        default: {
            break;
        }
    }
 
    if (decade && unit) strcat(ans, "-");
 
    switch (unit) {
        case 1: {
            strcat(ans, "one");
            break;
        }
        case 2: {
            strcat(ans, "two");
            break;
        }
        case 3: {
            strcat(ans, "three");
            break;
        }
        case 4: {
            strcat(ans, "four");
            break;
        }
        case 5: {
            strcat(ans, "five");
            break;
        }
        case 6: {
            strcat(ans, "six");
            break;
        }
        case 7: {
            strcat(ans, "seven");
            break;
        }
        case 8: {
            strcat(ans, "eight");
            break;
        }
        case 9: {
            strcat(ans, "nine");
            break;
        }
        default: {
            break;
        }
    }
}
 
int main() {
    char a[30] = "", b[30] = "";
    scanf("%s %s", a, b);
 
    numToStr(strToNum(a) + strToNum(b));
    puts(ans);
    return 0;
}

有点繁琐了,偷个懒copy代码叭,是开篇提到的佬的代码

60.删除前后缀

#include<stdio.h>
#include<string.h>
#define STLEN 1000

void str_removeprefix(char str[],char prefix[])
{
    int len=strlen(prefix);
    while(strncmp(str,prefix,len)==0){
        memmove(str,str+len,strlen(str)-len+1);
    }
    puts(str);
}

void str_removesuffix(char str[],char suffix[])
{
    int len=strlen(suffix);
    /*for(int i=len;i<strlen(str);i+=len)   这段代码有问题,虽然AC了但是不对*/
    while(1){
        if(strncmp(str+strlen(str)-len,suffix,len)==0){
            memmove(str,str,strlen(str)-len);
            str[strlen(str)-len]='\0';
        }
        else break;
    }
    puts(str);
}

int main()
{
    char str1[STLEN],words[STLEN],str2[STLEN];
    scanf("%[^\n] %[^\n]",str1,words);
    memmove(str2,str1,strlen(str1)+1);

    str_removeprefix(str1,words);
    str_removesuffix(str2,words);

    return 0;
}

61-79复杂数据

61.时钟A-B

#include<stdio.h>
#include<time.h>

int main()
{
    struct tm begin_tm={0},end_tm={0};
    scanf("%d %d %d",&begin_tm.tm_year,&begin_tm.tm_mon,&begin_tm.tm_mday);
    scanf("%d %d %d",&end_tm.tm_year,&end_tm.tm_mon,&end_tm.tm_mday);

    begin_tm.tm_year-=1900,begin_tm.tm_mon-=1;
    end_tm.tm_year-=1900,end_tm.tm_mon-=1;

    time_t begin=mktime(&begin_tm);
    time_t end=mktime(&end_tm);

    printf("%.6lf",difftime(begin,end));
    return 0;
}

62.三元搜索

#include<stdio.h>

int TernarySearch(int A[],int left,int right,int key)
{
    int mid1=left+(right-left)/3;
    int mid2=right-(right-left)/3;//划分数组
    if(key==A[mid1])return mid1;
    if(key==A[mid2])return mid2;

    if(key<A[mid1]&&key>=A[left]){
        return TernarySearch(A,left,mid1-1,key);
    }
    if(key>A[mid2]&&key<=A[right]){
        return TernarySearch(A,mid2+1,right,key);
    }
    if(key>A[mid1]&&key<A[mid2]){
        return TernarySearch(A,mid1+1,mid2-1,key);
    }
    return -1;
}

int main()
{
    int n,key;
    scanf("%d",&n);
    int A[n];

    for(int i=0;i<n;i++){
        scanf("%d",&A[i]);
    }
    scanf("%d",&key);//输入数据

    int i=TernarySearch(A,0,n-1,key);
    printf("%d in [%d]",key,i);
    return 0;
}

63.长安

#include<stdio.h>

int CalPath(int sx,int sy,int dx,int dy)
{
    float res=1;
    int m=dx+dy-sx-sy,n=dx-sx;
    for(int i=1;i<=n;i++){
        res=res*m/i;
        m-=1;
    }
    return (int)res;
}

int main()
{
    int dx,dy,ex,ey,temp1,temp2,ans;//d-->destination;e-->exhibit
    while(1){
        scanf("%d %d %d %d",&dx,&dy,&ex,&ey);
        if(dx<=0||dy<=0||ex<=0||ey<=0)
            break;

        if(dx==ex&&dy==ey){
            ans=0;
        }

        if(dx<ex||dy<ey){
            ans=CalPath(1,1,dx,dy);
        }
        else{
            temp1=CalPath(1,1,dx,dy);
            temp2=CalPath(1,1,ex,ey)*CalPath(ex,ey,dx,dy);
            ans=temp1-temp2;
        }
        printf("%d\n",ans);
    }
    return 0;
}

题图有误,起点为(1,1)

64.有效表达式

#include<stdio.h>
#define SIZE 20
int C[SIZE*2+1][SIZE*2+1];


int main()
{
    int n;
    scanf("%d",&n);

    for(int i=1;i<=2*n;i++)
        C[i][0]=C[i][i]=1;

    for(int i=2;i<=SIZE*2;i++){
        for(int j=1;j<i;j++){
            C[i][j]=C[i-1][j-1]+C[i-1][j];
        }
    }
    printf("%d\n",C[2*n][n]-C[2*n][n+1]);
    return 0;
}

卡特兰数

65.GPS通讯协议

#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>

char A[100];
char B[7];
int C[3];

bool verify(long a)
{
    char *p;
    long b=A[1];
    for(p=A+2;*p!='*';p++){
        b=(*p)^b;
    }
    if(b==a)return true;
    else return false;
}


bool verifyGPRMC()
{
    char Sub[10];
    char *end;
    strcpy(Sub,strrchr(A,'*')+1);
    long a=strtol(Sub,&end,16);
    //printf("%x\n",a);
    if(verify(a))
        return true;
    else return false;
}



int main()
{
    int a;
    while(1){
        scanf("%[^\n]",A);
        getchar();
        if(strncmp(A,"END",3)==0)
            break;
        if(strncmp(A,"$GPRMC",6)==0){
            if(verifyGPRMC()){
                strncpy(B,strchr(A,',')+1,6);
                B[6]='\0';
                a=atoi(B);

                C[0]=((a/10000%100)+8)%24;
                C[1]=a/100%100;
                C[2]=a%100;

                for(int i=0;i<3;i++){
                    if(C[i]<10){
                        printf("0");
                    }
                    printf("%d",C[i]);
                    if(i!=2){
                        printf(":");
                    }
                }
                printf("\n");
            }
            else printf("error\n");
        }
    }
    return 0;
}

66.Arduino显示

#include<stdio.h>

int Cost[10]={6,2,5,5,4,5,6,3,7,6};

int cost(int n)
{
    int num=0;
    do{
        num+=Cost[n%10];
        n/=10;
    }while(n);
    return num;
}

int main()
{
    int n,ans=0;
    scanf("%d",&n);
    n-=4;
    if(n){
        for(int i=0;i<=111;i++)
           for(int j=0;j<=111;j++){
               if(cost(i)+cost(j)+cost(i+j)==n)
                   ans++;
           }
    }
    printf("%d",ans);
    return 0;
}

打表也行

67.循环排序

#include<stdio.h>

void Cyclesort(int A[],int n)
{
    for(int i=0;i<n;i++){
        int item=A[i],pos=i;
        for(int j=i+1;j<n;j++){
            if(A[j]<item){
                pos++;
            }
        }
        if(pos==i) continue;

        else{
            int t=A[pos];
            A[pos]=item;
            item=t;
        }
        while(pos!=i){//使A[i]位应有的正确数字归位并顺手排序
            pos=i;
            for(int j=i+1;j<n;j++){
                if(A[j]<item){
                    pos++;
                }
            }
            while(item==A[pos])pos++;//考虑有相同的数
            int t=A[pos];
            A[pos]=item;
            item=t;
        }
        /*for(int i=0;i<n;i++){
        printf("%d ",A[i]);
    }
    printf("\n");*/
    }

}

int main()
{
    int n;
    scanf("%d",&n);
    int A[n];
    for(int i=0;i<n;i++){
        scanf("%d",&A[i]);
    }

    Cyclesort(A,n);
    for(int i=0;i<n;i++){
        printf("%d ",A[i]);
    }

    return 0;
}

68.DNA双螺旋结构

#include<stdio.h>
char A[3][17]={"ATTAATTATAGCTAGC","CGCGATATTAATATGC","ATCGTACGCGTAGCAT"};


int main()
{
    int n;
    scanf("%d",&n);

    for(int i=0;i*2<n;i++){
        int t=i%3,spacet=4,space=4;
        for(int j=0;j<8;j+=2){
            printf("%*c",space,A[t][j]);
            for(int k=1;k<=(spacet-space)*2;k++)printf("-");
            printf("%c",A[t][j+1]);
            space--;
            printf("\n");
        }
            space++;
        for(int j=8;j<16;j+=2){
            printf("%*c",space,A[t][j]);
            for(int k=1;k<=(spacet-space)*2;k++)printf("-");
            printf("%c",A[t][j+1]);
            space++;
            printf("\n");
        }
    }


    return 0;
}

没见过这么写碱基序列的,一开始都没看懂

69.加密字串

#include<stdio.h>
#include<string.h>


char s[100];
int vis[26];


int main()
{
    int x,n;
    scanf("%[^\n] %d",s,&x);
    n=strlen(s);
    for(int i=0;i<n;i++){
        vis[s[i]-'a']++;
    }
    for(int i=0;i<n;i++){
        if(vis[s[i]-'a']%2){
                s[i]=((s[i]-'a'-x)%26+26)%26+'a';//-x后可能小于0
        }
        else s[i]=(s[i]-'a'+x)%26+'a';
    }
    printf("%s\n",s);
    return 0;
}

70.PID控制

#include<stdio.h>

typedef struct PIDController{
    double Kp,Ki,Kd;
    double preError,integral;
}PIDData;

double PIDCalculate(PIDData *pid,double setpoint,double measuredValue)
{
    double error=setpoint-measuredValue;
    pid->integral+=error;
    double differential=error-pid->preError;
    double output=pid->Kp*error+pid->integral*(pid->Ki)+pid->Kd*differential;
    pid->preError=error;
    return output;
}

int main()
{
    double setpoint,measuredValue;
    PIDData pid;
    int n;

    pid.preError=0,pid.integral=0;
    scanf("%lf %lf %lf",&pid.Kp,&pid.Ki,&pid.Kd);
    scanf("%lf %lf",&setpoint,&measuredValue);
    scanf("%d",&n);

    for(int i=1;i<=n;i++){
        double output=PIDCalculate(&pid,setpoint,measuredValue);
        measuredValue+=output;
        printf("%d %.6lf\n",i,measuredValue);

    }
    return 0;
}

71-80数据结构

71.日出日落时间(WA)

72.热能计算

#include<stdio.h>

int main()
{
    int Ti,Tf,Tt,cL,cC;
    double QL,QC,Total,mL,mC;


    scanf("%d %d",&Ti,&Tf);
    scanf("%lf %d",&mL,&cL);
    scanf("%lf %d",&mC,&cC);
    Tt=Tf-Ti;


    QL=Tt*mL*cL;
    QC=Tt*mC*cC;
    Total=QL+QC;


    printf("%.2lfkJ,%.2lf%%,%.2lf%%\n",Total/1000,QC/Total,QL/Total);

    return 0;
}

73.中位数

#include<stdio.h>

int queue[1000];

int main()
{
    int t=0,i;
    do{
        do{
            scanf("%d",&i);
            if(i>0)queue[++t]=i;
        }while(i>0);
        if(i<0)break;

        for(int i=1;i<=t;i++){
            printf("%d ",queue[i]);
        }

        if(t%2==0){
            double temp=0;
            temp=queue[t/2]+queue[t/2+1];
            printf("%.6lf\n",temp/2);
        }
        else{
            printf("%.6lf\n",(double)queue[(t+1)/2]);
        }
    }while(i>=0);
    return 0;
}

74.晶体结构

#include<stdio.h>
#include<string.h>
#include<math.h>
#define PI 3.14159265358979323846


typedef struct DATA{
    double m;
    double APF;
    double r;
}D;

double Avo=6.022;
char Ele[3];
char List[][3]={"Po","Li","Na","Cr","Mn","Fe","Mo","Ta","Al","Ca","Ni","Cu","Ge","Ag","Pt","Au","Pb"};


D Po={208.998,0.52360,1.68};
D Li={6.941,0.68017,1.52};
D Na={22.989770,0.68017,1.86};
D Cr={51.9961,0.68017,1.28};
D Mn={54.938049,0.68017,1.27};
D Fe={55.845,0.68017,1.26};
D Mo={95.94,0.68017,1.39};
D Ta={180.9749,0.68017,1.46};
D Al={26.981538,0.74048,1.43};
D Ca={40.078,0.74048,1.97};
D Ni={58.6934,0.74048,1.24};
D Cu={63.546,0.74048,1.28};
D Ge={72.74,0.74048,1.22};
D Ag={107.8682,0.74048,1.44};
D Pt={195.078,0.74048,1.39};
D Au={196.96655,0.74048,1.44};
D Pb={207.2,0.74048,1.75};
D *p;
D *pList[17]={&Po,&Li,&Na,&Cr,&Mn,&Fe,&Mo,&Ta,&Al,&Ca,&Ni,&Cu,&Ge,&Ag,&Pt,&Au,&Pb};

int main()
{
    int n;
    scanf("%d",&n);
    while(n--){
        scanf("%s",Ele);
        for(int i=0;i<17;i++){
            if(strcmp(Ele,List[i])==0){
                p=pList[i];
                break;
            }
        }
        double V=4.0*PI*pow(p->r,3)/3.0;
        double ans=10.0*p->APF*p->m/Avo/V;
        printf("%.2lf\n",ans);
    }
    return 0;
}

75.火箭发射模拟

#include<stdio.h>
#define ts 0.1
//timestep

int main()
{
    double im,nm,bt,cE,g;//initialmass,netmass,burntime,cE,g
    scanf("%lf %lf %lf %lf %lf",&im,&nm,&bt,&cE,&g);

    double Al=0,v=0;//altitude,km->divede 1000;
    double lm=(im-nm)/bt;//lostmass
    double T=lm*cE;

    double a,delv,delAl;//a,deltaV,deltaAl
    while(bt>=0){
        a=T/im;
        delv=a*ts;
        v+=delv;
        delAl=v*ts;

        Al+=delAl;
        im-=lm*ts;
        bt-=ts;
    }
    printf("%.3lfkm",Al/1000);
    return 0;
}
//100000 10000 100 4000 9.81
//题设有误,g都没用上

题目计算公式有问题,g没用上

76.水下声学定位

#include<stdio.h>
#include<math.h>
#define PI 3.1415926


double Helen(double a,double b,double c)
{
    double q=(a+b+c)/2.0;
    return sqrt(q*(q-a)*(q-b)*(q-c));
}

int main()
{
    double a,b,c,d,e;
    scanf("%lf %lf %lf %lf %lf",&a,&b,&c,&d,&e);
    double S=Helen(a,b,e)+Helen(c,d,e);
    double angle = atan((4 * S) / (pow(b, 2) + pow(d, 2) - pow(a, 2) - pow(c, 2)));
    angle*=180.0/PI;
    printf("%.6lf %.1lf\n",S,angle);
    return 0;
}

77.原子记数

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct element{
    char name[3];
    int n;
}ELE[100];//element
int num=-1;


int getnum(char *p)
{
    int res=0;
    for(;*p>='0'&&*p<='9';p++){
        res=res*10+*p-'0';
    }
    return res+!res;
}

int cmp(const void*a,const void*b)
{
    struct element *aa=(struct element *)a;
    struct element *bb=(struct element *)b;
    return strcmp(aa->name,bb->name);

}
int main()
{
    char Com[100];//Compound
    scanf("%s",Com);
    int len=strlen(Com);

    for(int i=0;i<len;i++){
        if(Com[i]>='A'&&Com[i]<='Z'){
            if(Com[i+1]>='a'&&Com[i+1]<='z'){
                strncpy(ELE[++num].name,Com+i,2);
                ELE[num].n+=getnum(Com+i+2);
            }
            else{
                strncpy(ELE[++num].name,Com+i,1);
                ELE[num].n+=getnum(Com+i+1);
            }
        }
        else continue;
    }
    num++;

    qsort(ELE,num,sizeof(ELE[0]),cmp);
    int i=0,res;
    while(i<num){
        if(i+1<num&&strcmp(ELE[i].name,ELE[i+1].name)==0){
                res=ELE[i].n;
            while(i+1<num&&strcmp(ELE[i].name,ELE[i+1].name)==0){
                res+=ELE[i+1].n;
                i++;
            }
        }
        else res=ELE[i].n;
        printf("%s %d\n",ELE[i].name,res);
        i++;
    }


    return 0;
}

在这里插入图片描述
stdlib库里边的一个函数,好用的捏

78.成绩单

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct tagStudent{
    char id[11];
    char name[31];
    int score;
}ST;
ST LIST[50];


int cmp(const void *a,const void *b)
{
    ST *aa=(ST *)a;
    ST *bb=(ST *)b;
    int res=bb->score-aa->score;
    if(res==0){
        return strcmp(aa->id,bb->id);
    }
    else return res;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%s %s %d",LIST[i].id,LIST[i].name,&LIST[i].score);
    }
    qsort(LIST,n,sizeof(LIST[0]),cmp);
    for(int i=0;i<n;i++){
        printf("%s %s %d\n",LIST[i].id,LIST[i].name,LIST[i].score);
    }
    return 0;
}

79.卫星定位

#include <stdio.h>
#include <math.h>

#define N 11
#define c 299792.458

double X[N],A[N],B[N],C[N],T[N];

void scanf1(double A[N],int n)
{
    for(int i=0;i<n;i++){
        scanf("%lf",&A[i]);
    }
}



void print1(double A[N],int n) { //输出一个矢量
	int i,tmp;
	double a;
	for (i=0; i<n-1; i++){
        tmp=(int)(A[i]*10000);
        a=(double)tmp/10000.0;
        printf("%.4lf,",a);
	}
    tmp=(int)(A[n-1]*10000);
    a=(double)tmp/10000.0;
    printf("%.4lf", a);

}

// 计算代数余子式函数,结果=dest
int GetCoFactor(double dest[N][N], double src[N][N], int row, int col, int n)
{
	int i, j;
	int colCount=0,rowCount=0;
	for(i=0; i<n; i++ ) {
		if( i!=row ) {
			colCount = 0;
            for(j=0; j<n; j++ )
				if( j != col ) { //当j不是元素时
					dest[rowCount][colCount] = src[i][j];
					colCount++;
				}
			rowCount++;
		}
	}
	return 1;
}

// 递归计算行列式,结果=返回值
double CalcDeterminant(double mat[N][N], int n)
{
	int i,j;
	double det = 0; //行列式值
	double minor[N][N]; // allocate 余子式矩阵

    // n 必须 >= 0,当矩阵是单个元素时停止递归
	if( n == 1 ) return mat[0][0];
	for(i = 0; i < n; i++ ) {
		GetCoFactor(minor, mat, 0, i , n);
		det += ( i%2==1 ? -1.0 : 1.0 ) * mat[0][i] * CalcDeterminant(minor,n-1);
	}
	return det;
}
// 伴随矩阵法矩阵求逆 , 结果存放到 inv 数组
void MatrixInversion(double J[N][N], int n)
{
	int i,j;
    double det, temp [N][N], minor[N][N];
    double inv[N][N];

	det = 1.0/CalcDeterminant(J,n); //计算行列式
	for(j=0; j<n; j++)
		for(i=0; i<n; i++) {
			// 得到矩阵A(j,i)的代数余子式
			GetCoFactor(minor,J,j,i,n);
			inv[i][j] = det*CalcDeterminant(minor,n-1);
			if( (i+j)%2 == 1)
				inv[i][j] = -inv[i][j];
		}
	//结果存回J矩阵
	for(j=0; j<n; j++)
		for(i=0; i<n; i++)
			J[i][j] = inv[i][j];
}

// 由Xn计算函数Fn,结果存放到 F
void CalcF(double F[N],double X[N],int n) {
	double f;
	int i;
	for (i=0; i<n; i++) {
		switch (i+1) {
			case 1:
				f=(X[0]-A[0])*(X[0]-A[0])+(X[1]-B[0])*(X[1]-B[0])+(X[2]-C[0])*(X[2]-C[0])-(c*(T[0]-X[3]))*(c*(T[0]-X[3]));
				break;
			case 2:
				f=(X[0]-A[1])*(X[0]-A[1])+(X[1]-B[1])*(X[1]-B[1])+(X[2]-C[1])*(X[2]-C[1])-(c*(T[1]-X[3]))*(c*(T[1]-X[3]));
				break;
			case 3:
				f=(X[0]-A[2])*(X[0]-A[2])+(X[1]-B[2])*(X[1]-B[2])+(X[2]-C[2])*(X[2]-C[2])-(c*(T[2]-X[3]))*(c*(T[2]-X[3]));
                break;
            case 4:
				f=(X[0]-A[3])*(X[0]-A[3])+(X[1]-B[3])*(X[1]-B[3])+(X[2]-C[3])*(X[2]-C[3])-(c*(T[3]-X[3]))*(c*(T[3]-X[3]));
		}
		F[i]=f;
	}
}

// 由Xn计算偏导数Jacobian矩阵F'n,结果存放到 J
void CalcJ(double J[N][N],double X[N],int n) {
	double f;
	int i,j;
	for (i=0; i<n; i++)
		switch (i+1) {
			case 1:
				for (j=0; j<n; j++) {
					switch (j+1) {
						case 1: f=2*(X[0]-A[0]);break; // J1.1=2(x-A1)
						case 2: f=2*(X[1]-B[0]);break; // J1.2=2(y-B1)
						case 3: f=2*(X[2]-C[0]);break;  // J1.3=2(z-C1)
                        case 4: f=2*c*c*(T[0]-X[3]);break;//J1.4=2*c^2(t1-d)
					}
					J[i][j]=f;
				}
				break;
			case 2:
				for (j=0; j<n; j++) {
					switch (j+1) {
						case 1: f=2*(X[0]-A[1]);break; // J1.1=2(x-A1)
						case 2: f=2*(X[1]-B[1]);break; // J1.2=2(y-B1)
						case 3: f=2*(X[2]-C[1]);break;  // J1.3=2(z-C1)
                        case 4: f=2*c*c*(T[1]-X[3]);break;//J1.4=2*c^2(t1-d)
					}
					J[i][j]=f;
				}
				break;
			case 3:
				for (j=0; j<n; j++) {
					switch (j+1) {
						case 1: f=2*(X[0]-A[2]);break; // J1.1=2(x-A1)
						case 2: f=2*(X[1]-B[2]);break; // J1.2=2(y-B1)
						case 3: f=2*(X[2]-C[2]);break;  // J1.3=2(z-C1)
                        case 4: f=2*c*c*(T[2]-X[3]);break;//J1.4=2*c^2(t1-d)
					}
					J[i][j]=f;
				}
				break;
            case 4:
				for (j=0; j<n; j++) {
					switch (j+1) {
						case 1: f=2*(X[0]-A[3]);break; // J1.1=2(x-A1)
						case 2: f=2*(X[1]-B[3]);break; // J1.2=2(y-B1)
						case 3: f=2*(X[2]-C[3]);break;  // J1.3=2(z-C1)
                        case 4: f=2*c*c*(T[3]-X[3]);break;//J1.4=2*c^2(t1-d)
					}
					J[i][j]=f;
				}
				break;
		}
}

// 计算 J^-1* F,结果存放到 R
void CalcJF(double R[N], double J[N][N], double F[N], int n) {
	int i,j,k;
	for (i=0; i<n; i++) {
		R[i]=0.0;
		for (j=0; j<n; j++)
			R[i] = R[i] + J[i][j]*F[j];
	}
}

// 计算 X=X0-R,结果存放到 X
void CalcX(double X[N],double X0[N],double R[N],int n) {
	int i;
	for (i=0; i<n; i++)
		X[i]=X0[i]-R[i];
}

// 计算 A=B,结果存放到 A
void AequB(double A[N],double B[N],int n) {
	int i;
	for (i=0; i<n; i++)
		A[i]=B[i];
}

// 计算 F-
double Ferror(double F[N], int n) {
	double m=0;
	int i;
	for (i=0; i<n; i++) {
		double t=fabs(F[i]);
		if (m<t) m = t;
	}
	return m;
}

// Newton–Raphson method 牛顿迭代法求非线性方程组的根,存放到X0
void mvNewtons(double X0[N], int n, double e) {
	// Guess为初始猜测值 e为迭代精度要求
	int k;
	double J[N][N],Y[N][N];
	double X[N],R[N],F[N];
	//X0一开始为初始猜测值
	for (k=1; k<=20; k++) { //限定20次迭代
		//printf("-------------- n=%d\n",k);
		//printf("X\n");
		//print1(X0,n); //输出X0
		CalcF(F,X0,n); //计算F矩阵
		//printf("F\n"); //观察 F
		//print1(F,n); //输出F
		CalcJ(J,X0,n); //计算Jacobian矩阵F'n(x0)
		//printf("J\n");
		//print2(J,n); //观察 J
		MatrixInversion(J, n); // 求J的逆矩阵 J^-1
		CalcJF(R,J,F,n); // R=J^-1 * F
		CalcX(X,X0,R,n); // X=X0-R
		AequB(X0,X,n); // X0=X 下次迭代
		if (Ferror(F,n)<e) break; //达到精度要求,终止迭代
	}
}

int main() {
	int n=4;
    scanf("%lf %lf %lf",&A[0],&B[0],&C[0]);
    scanf("%lf %lf %lf",&A[1],&B[1],&C[1]);
    scanf("%lf %lf %lf",&A[2],&B[2],&C[2]);
    scanf("%lf %lf %lf",&A[3],&B[3],&C[3]);
	scanf1(T,n);
	scanf1(X,n);
	mvNewtons(X,n,1e-6); //根存放在X
    print1(X,3);
	return 0;
}

资料代码给的是计算三阶矩阵的,修改成四阶,并且截断并不四舍五入。

80.几何约束

#include<stdio.h>
#include<stdbool.h>
#define N 21

int X1[N],X2[N],Y1[N],Y2[N];

int max(int a,int b)
{
    return a>b?a:b;
}

int min(int a,int b)
{
    return a>b?b:a;
}

int crossproduct(int x1,int y1,int x2,int y2,int a,int b)
{
    return (x2-x1)*(b-y1)-(a-x1)*(y2-y1);
}

bool judge(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4)
{
    if(max(x3,x4)<min(x1,x2)||min(x3,x4)>max(x1,x2)||max(y3,y4)<min(y1,y2)||min(y3,y4)>max(y1,y2))
        return false;

    double cp1=crossproduct(x1,y1,x2,y2,x3,y3);
    double cp2=crossproduct(x1,y1,x2,y2,x4,y4);
    double cp3=crossproduct(x3,y3,x4,y4,x1,y1);
    double cp4=crossproduct(x3,y3,x4,y4,x2,y2);

    if((cp1*cp2<=0)&&(cp3*cp4<=0)){
        return true;
    }

    return false;
}


int main()
{
    int n,res=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d %d %d %d",&X1[i],&Y1[i],&X2[i],&Y2[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(judge(X1[i],Y1[i],X2[i],Y2[i],X1[j],Y1[j],X2[j],Y2[j])){
                printf("X: #%d #%d\n",i,j);
                res++;
            }
        }
    }
    printf("n=%d\n",res);
    return 0;
}

81-90算法策略

这一季我打算算按照各个算法的顺序做。
81-84 动态规划
85-87 贪心
88-89 回溯
90 分治

81.危险的组合

#include<stdio.h>
#include<math.h>

int dp[31];

int main()
{
    int n;

    dp[1]=0;
    dp[2]=0;
    dp[3]=1;
    for(int i=4;i<=30;i++){
        dp[i]=2*dp[i-1]+(int)pow(2,i-4)-dp[i-4];
    }
    while(1){
        scanf("%d",&n);
        if(n<=0)break;
        printf("%d\n",dp[n]);
    }
}

这道题用危险方案来算或者安全方案来算都可以
设第i个盒子危险方案数为fi,则fi=f(i-1)+2^(i-4)-f(i-4);
设安全方案数为fi,则fi=f(i-1)+f(i-2)+f(i-3);
打表也行

82.上楼梯

#include<stdio.h>
#include<string.h>

#define LIMIT 1000000007

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    unsigned dp[n+1];
    memset(dp,-1,(n+1)*sizeof(unsigned));

    while(m--){
        int i;
        scanf("%d",&i);
        dp[i]=0;
    }

    dp[1]=dp[1]?1:0;
    dp[2]=dp[2]?(dp[1]?2:1):0;

    for(int i=3;i<=n;i++){
        if(dp[i]){
            dp[i]=(dp[i-1]+dp[i-2])%LIMIT;
        }
    }
    printf("%u\n",dp[n]);
    return 0;
}

83.打字机

#include<stdio.h>
#include<string.h>
#define MAX 101

char str[MAX];
int dp[MAX];


int main()
{
    scanf("%s",str);
    int LEN=strlen(str);

    for(int i=0;i<LEN;i++){
        if(str[i]=='m'||str[i]=='w'){
            printf("0\n");
            return 0;
        }
    }

    dp[0]=1;
    dp[1]=1;

    for(int i=1;i<LEN;i++){
        dp[i+1]=dp[i];
        if((str[i]=='u'&&str[i-1]=='u')||(str[i]=='n'&&str[i-1]=='n')){
            dp[i+1]+=dp[i-1];
        }
    }

    printf("%d\n",dp[LEN]);
    return 0;
}

84.挑选

#include<stdio.h>
#define MAX 1000

int arr[MAX];
int dp[MAX];
void quicksort(int n,int left,int right)
{
    int i,j,t;
    if(left<right){
        i=left;j=right+1;
        while(1){
            while(i+1<n&&arr[++i]<arr[left]);
            while(j-1>-1&&arr[--j]>arr[left]);
            if(i>=j)break;
            t=arr[i],arr[i]=arr[j],arr[j]=t;
        }
        t=arr[left],arr[left]=arr[j],arr[j]=t;
        quicksort(n,left,j-1);
        quicksort(n,j+1,right);
    }

}

int max(int n)
{
    int max=0;
    for(int i=0;i<n;i++){
        if(max<dp[i])max=dp[i];
    }
    return max;
}


int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
    scanf("%d",&arr[i]);
    }
    quicksort(n,0,n-1);
    /*for(int i=0;i<n;i++){
        printf("%d ",arr[i]);
    }*/
    dp[0]=arr[0];

    for(int i=1;i<n;i++){
        if(arr[i]==arr[i-1]){
            if(arr[i]>=0)dp[i]=dp[i-1]+arr[i];
            else dp[i]=dp[i-1];
        }
        else{
            int j;
            for(j=i-1;arr[j]==arr[i]-1;j--);
            if(j>=0){
                dp[i]=dp[j]+arr[i];
            }
            else{
                dp[i]=arr[i];
            }
        }
    }
    int res=max(n);
    printf("%d\n",res);
    return 0;
}

85.汤包

#include<stdio.h>
#include<stdlib.h>
#define MAX 1000

int bg[MAX],cost[MAX],seq[MAX];

int cmp(const void *a,const void *b)
{
    int *aa=(int *)a;
    int *bb=(int *)b;
    int tmp=(bg[*aa]+cost[*aa])-(bg[*bb]+cost[*bb]);
    if(tmp==0){
        return *aa-*bb;
    }
    else return tmp;
}

int main()
{
    int n;
    scanf("%d",&n);

    for(int i=0;i<n;i++){
        scanf("%d%d",&bg[i],&cost[i]);
        seq[i]=i;
    }

    qsort(seq,n,sizeof(int),cmp);
    for(int i=0;i<n;i++){
        printf("%d ",seq[i]+1);
    }
    return 0;
}

86.绝对差

#include<stdio.h>
#include<stdlib.h>

int cmp(const void *a,const void *b)
{
    int aa=*(int *)a;
    int bb=*(int *)b;
    return aa-bb;
}
/*
void quicksort(int arr[],int n,int left,int right)
{
    int i,j,t;
    if(left<right){
        i=left;j=right+1;
        while(1){
            while(i+1<n&&arr[++i]<arr[left]);
            while(j-1>-1&&arr[--j]>arr[left]);
            if(i>=j)break;
            t=arr[i],arr[i]=arr[j],arr[j]=t;
        }
        t=arr[left],arr[left]=arr[j],arr[j]=t;
        quicksort(arr,n,left,j-1);
        quicksort(n,j+1,right);
    }
}
*/


//为了避免有序数组这种极端情况,可以随机化基准元素;
/*
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

// 随机化选择基准元素
int randomizedPartition(int arr[], int left, int right) {
    int pivotIndex = left + rand() % (right - left + 1);
    swap(&arr[pivotIndex], &arr[right]); // 将基准移到末尾
    int pivot = arr[right];
    int i = left - 1;
    for (int j = left; j < right; j++) {
        if (arr[j] < pivot) {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[right]); // 将基准放到最终位置
    return i + 1;
}

// 快速排序递归函数
void quickSort(int arr[], int left, int right) {
    if (left >= right) {
        return;
    }
    // 随机化分区
    int pivotIndex = randomizedPartition(arr, left, right);
    // 递归排序左子数组
    quickSort(arr, left, pivotIndex - 1);
    // 递归排序右子数组
    quickSort(arr, pivotIndex + 1, right);
}

// 测试快速排序函数
int main() {
    srand(time(NULL)); // 初始化随机数种子
    int arr[] = {10, 7, 8, 9, 1, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    quickSort(arr, 0, n - 1);
    
    printf("Sorted array: \n");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}
*/
int main()
{
    int n,min;
    scanf("%d",&n);
    int arr[n];
    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
    }
    qsort(arr,n,sizeof(int),cmp);//qsort不一定就是quicksort
    min=arr[1]-arr[0];
    for(int i=2;i<n;i++){
        int temp=arr[i]-arr[i-1];
        if(min>temp)min=temp;
    }
    printf("%d",min);
    return 0;
}

87.三角形

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<stdbool.h>


void quicksort(int arr[],int left,int right)
{
    if(left>=right)return;
    srand(time(NULL));
    int idx=rand()%(right-left)+left;
    int flag=arr[idx],head=left-1,tail=right+1;
    while(head<tail){
        while(head+1<right+1&&arr[++head]<flag);
        while(tail-1>-1&&arr[--tail]>flag);
        if(head<tail){
            int tmp=arr[head];
            arr[head]=arr[tail];
            arr[tail]=tmp;
        }
    }
    quicksort(arr,left,tail);
    quicksort(arr,tail+1,right);
}
//前面说的随机化基准元素,基本上从佬那边copy的,加上了两个判断防止越界

bool MaxTri(int arr[],int n)
{
    for(int i=n-1;i>1;i--){
        if(arr[i]<arr[i-1]+arr[i-2]){
            printf("%d %d %d\n",arr[i-2],arr[i-1],arr[i]);
            return false;
        }
    }
    return true;
}

int main()
{
    int n;
    scanf("%d",&n);
    int arr[n];
    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
    }

    quicksort(arr,0,n-1);

    if(MaxTri(arr,n)){
        printf("-1\n");
    }

    return 0;
}

88.游乐园

#include<stdio.h>
#include<stdbool.h>
#include<string.h>

int dis[13][13];
int res=0,temp=0;
bool flag[13];

bool dead(int start,int n)
{
    int i;
    for(i=1;i<=n;i++){
        if(flag[i]==0)break;
    }
    if(i==n+1)return true;
    //n个结点全部遍历完;

    for(i=1;i<=n;i++){
        if(dis[start][i]&&flag[i]==0)break;
    }
    if(i==n+1)return true;
    //deadend

    return false;
}


void backtrack(int start,int n)
{
    if(dead(start,n)){
        res=res>temp?res:temp;
        return;
    }

    for(int i=1;i<=n;i++){
        if(flag[i]==0&&dis[start][i]){
            flag[i]=true;
            temp+=dis[start][i];
            backtrack(i,n);
            flag[i]=false;
            temp-=dis[start][i];
        }
    }

}

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);

    int j,k,l;
    for(int i=1;i<=m;i++){
        scanf("%d %d %d",&j,&k,&l);
        dis[j][k]=l;
        dis[k][j]=l;
    }

    for(int i=1;i<=n;i++){
        memset(flag,0,sizeof(flag));
        flag[i]=true;
        backtrack(i,n);
    }
    printf("%d\n",res);
    return 0;
}

89.和字符串

#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>

#define MAX 1000
char str[MAX];
char substring[MAX];

long getnum(int start,int len)
{
    char *end;
    strncpy(substring,str+start,len);
    return strtoul(substring,&end,10);
}

int digit(long n)
{
    int res=0;
    while(n){
        res++;
        n/=10;
    }
    return res;
}

bool backtrack(int n,int begin,int d1,int d2)
{
    if(begin+d1+d2>=n)
        return true;

    unsigned long num1=getnum(begin,d1);
    unsigned long num2=getnum(begin+d1,d2);
    unsigned long num3=getnum(begin+d1+d2,digit(num1+num2));

    if(num1+num2==num3) return backtrack(n,begin+d1,d2,digit(num3));

    return false;
}

void isADDstr()
{
    int len=strlen(str);

    for(int i=1;i<=len/2;i++){
        if(backtrack(len,0,i,i)){
            printf("true\n");
            return;
        }
    }
    printf("false\n");
}

int main()
{
    scanf("%s",str);
    memset(substring,'\0',sizeof(substring));
    isADDstr();
    return 0;
}

90.子数组最大和

这道题说的子数组指的是连续元素

#include<stdio.h>
#define MAX 100

int arr[MAX],dp[MAX];

int main()
{
    int n;
    scanf("%d",&n);

    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
    }

    dp[0]=arr[0];
    for(int i=1;i<n;i++){
        dp[i]=arr[i]>(dp[i-1]+arr[i])?arr[i]:(dp[i-1]+arr[i]);
    }
    
    int res=dp[0];
    for(int i=1;i<n;i++){
        if(dp[i]>res)res=dp[i];
    }
    printf("%d",res);
    return 0;
}

91-100思维体操

91.零钞

#include<stdio.h>


void GiveChange(int req)
{
    int one=0,two=0,five=0,ten=0;
    while(req){
        if(req-10>=0){
            req-=10;
            ten++;
        }
        else if(req-5>=0){
            req-=5;
            five++;
        }
        else if(req-2>=0){
            req-=2;
            two++;
        }
        else if(req-1>=0){
            req-=1;
            one++;
        }
    }
    if(one){
        printf("1=%d\n",one);
    }
    if(two){
        printf("2=%d\n",two);
    }
    if(five){
        printf("5=%d\n",five);
    }
    if(ten){
        printf("10=%d\n",ten);
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    GiveChange(n);

    return 0;
}

贪心

92.气体扩散

#include<stdio.h>
#include<math.h>


int main()
{
    double a,b;
    scanf("%lf %lf",&a,&b);
    printf("%.4lf",sqrt(b/a));

    return 0;
}

93.左右操作

#include<stdio.h>
#include<string.h>
#include<time.h>
#include<stdlib.h>

void quicksort(char arr[],int left,int right)
{
    if(left>=right)return;
    srand(time(NULL));
    int idx=rand()%(right-left)+left;
    int flag=arr[idx],head=left-1,tail=right+1;
    while(head<tail){
        while(head+1<right+1&&arr[++head]>flag);
        while(tail-1>-1&&arr[--tail]<flag);
        if(head<tail){
            int tmp=arr[head];
            arr[head]=arr[tail];
            arr[tail]=tmp;
        }
    }
    quicksort(arr,left,tail);
    quicksort(arr,tail+1,right);
}

void swap(char *a,char *b)
{
    int tmp;
    tmp=*a;
    *a=*b;
    *b=tmp;
}

void reverse(char *arr,int len)
{
    char *p=arr;
    int n=1;
    while(n<len){
        swap(p+n-1,p+len-1);
        n++;
        len--;
    }
}

int main()
{
    char arr[1001]="";
    scanf("%s",arr);
    int len=strlen(arr),llen,rlen;
    if(len%2){
        llen=rlen=(len-1)/2;
    }
    else{
        llen=rlen=len/2;
    }
    //printf("%d",rlen);
    quicksort(arr,0,llen-1);
    /*for(int i=0;i<llen;i++){
        printf("%c",arr[i]);
    }*/
    if(len%2){
        reverse(arr+llen+1,rlen);
    }
    else reverse(arr+llen,rlen);

    printf("%s",arr);

    return 0;
}
/*
abcdefx181292
*/

94.圆周率

#include<stdio.h>

int main()
{
    int n;
    scanf("%d",&n);
    double pi=3,p,sgn=1;
    int i;
    for(p=2,i=2;i<=n;i++,p+=2,sgn*=-1){
        double tmp=p*(p+1)*(p+2);
        pi+=sgn*4/tmp;
    }
    printf("%.7lf",pi);
    return 0;
}

95.平方根

#include<stdio.h>
#include<math.h>

int main()
{
    int n;
    scanf("%d",&n);
    FILE *p=fopen("rr.dat","w");
    for(int i=1;i<=n;i++){
        fprintf(p,"%.6lf\n",sqrt(i));
    }
    fclose(p);

    p=fopen("rr.dat","r");
    for(int i=1;i<=n;i++){
        double ans;
        fscanf(p,"%lf",&ans);
        printf("%.6lf ",ans);
    }
    fclose(p);

    return 0;
}

96.阿克曼函数

#include<stdio.h>

int Ackermann(int m,int n)
{
    if(m==0) return n+1;
    if(n==0) return Ackermann(m-1,1);
    else return Ackermann(m-1,Ackermann(m,n-1));
}

int main()
{
    int m,n;
    scanf("%d %d",&m,&n);
    int ans=Ackermann(m,n);
    printf("%d",ans);
    return 0;
}

97.马赫数

#include<stdio.h>
#include<math.h>


int main()
{
    double res,v,c,t;
    scanf("%lf %lf",&v,&t);
    c=331.3*sqrt(1+t/273.15);
    v/=3.6;
    res=v/c;
    printf("%.3lf ",res);
    if(res<0.8) printf("subsonic");
    else if(res>=0.8&&res<1.2) printf("transonic");
    else if(res>=1.2&&res<5.0) printf("supersonic");
    else printf("hypersonic");

    return 0;
}

98.重复元素

#include<stdio.h>

void quicksort(int arr[],int n,int left,int right)
{
    int t,i,j;
    if(left<right){
        i=left,j=right+1;
        while(1){
            while(i+1<n&&arr[++i]<arr[left]);
            while(j-1>-1&&arr[--j]>arr[left]);
            if(i>=j)break;
            t=arr[i],arr[i]=arr[j],arr[j]=t;
        }
        t=arr[left],arr[left]=arr[j],arr[j]=t;
        quicksort(arr,n,left,j-1);
        quicksort(arr,n,j+1,right);
    }

}


int main()
{
    int n,ans=0;
    scanf("%d",&n);
    int arr[n];
    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
    }

    quicksort(arr,n,0,n-1);
    /*for(int i=0;i<n;i++){
        printf("%d ",arr[i]);
    }
    printf("\n");*/
    for(int i=0;i<n;i++){
        if(i+1<n&&arr[i+1]==arr[i]){
            ans++;
        }
    }
    printf("%d",ans);
    return 0;
}

99.空中交通管制

#include<stdio.h>
#include<math.h>
#include<limits.h>

typedef struct STASTISTIC{
    char name[6];
    int x;
    int y;
}STA;

int main()
{

    int n,a,b;
    double dis=INT_MAX;
    scanf("%d",&n);
    STA S1[n],*ps1;
    ps1=S1;
    for(int i=0;i<n;i++){
        scanf("%s %d %d",S1[i].name,&S1[i].x,&S1[i].y);
    }

    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            double tmp;
            tmp=pow(((ps1+i)->x)-((ps1+j)->x),2)+pow(((ps1+i)->y)-((ps1+j)->y),2);
            tmp=sqrt(tmp);
            if(tmp<dis){
                dis=tmp;
                a=i;
                b=j;
            }
        }
    }
    printf("%s-%s %.4lf",(ps1+a)->name,(ps1+b)->name,dis);

    return 0;
}

100.机场翻牌显示

#include<stdio.h>

int trans(char *a,char *b)
{
    int tmp=0,sub;
    for(int i=0;i<2;i++){
        sub=*(b+i)-*(a+i);
        if(sub<0)sub+=26;
        tmp+=sub;
    }
    for(int i=2;i<6;i++){
        sub=*(b+i)-*(a+i);
        if(sub<0)sub+=10;
        tmp+=sub;
    }
    return tmp;
}


int main()
{
    int res;
    char ini[7],end[7];
    scanf("%s %s",ini,end);
    res=trans(ini,end);
    printf("%d",res);
    return 0;
}

西北工业大学NOJC程序设计习答案(非本人制作,侵删) 1.“1“的传奇 2.A+B 3.A+BⅡ 4.AB 5.ACKERMAN 6.Arithmetic Progressions 7.Bee 8.Checksum algorithm 9.Coin Test 10.Dexter need help 11.Double 12.Easy problem 13.Favorite number 14.Graveyard 15.Hailstone 16.Hanoi Ⅱ 17.Houseboat 18.Music Composer 19.Redistribute wealth 20.Road trip 21.Scoring 22.Specialized Numbers 23.Sticks 24.Sum of Consecutive 25.Symmetric Sort 26.The Clock 27.The Ratio of gainers to losers 28.VOL大学乒乓球比赛 29.毕业设计论文打印 30.边沿与内芯的差 31.不会吧,又是A+B 32.不屈的小蜗 33.操场训练 34.插入链表节点 35.插入排序 36.插入字符 37.成绩表计算 38.成绩转换 39.出租车费 40.除法 41.创建与遍历职工链表 42.大数乘法 43.大数除法 44.大数加法 45.单词频次 46.迭代求根 47.多项式的猜想 48.二分查找 49.二分求根 50.发工资的日子 51.方差 52.分离单词 53.分数拆分 54.分数化小数 55.分数加减法 56.复数 57.高低交换 58.公园喷水器 59.韩信点兵 60.行程编码压缩算法 61.合并字符串 62.猴子分桃 63.火车站 64.获取指定二进制位 65.积分计算 66.级数和 67.计算A+B 68.计算PI 69.计算π 70.计算成绩 71.计算完数 72.检测位图长宽 73.检查图像文件格式 74.奖金发放 75.阶乘合计 76.解不等式 77.精确幂乘 78.恐怖水母 79.快速排序 80.粒子裂变 81.链表动态增长或缩短 82.链表节点删除 83.两个整数之间所有的素数 84.路痴 85.冒泡排序 86.你会存钱吗 87.逆序整数 88.排列 89.排列分析 90.平均值函数 91.奇特的分数数列 92.求建筑高度 93.区间内素数 94.三点顺序 95.山迪的麻烦 96.删除字符 97.是该年的第几天 98.是该年的第几天? 99.数据加密 100.搜索字符 101.所有素数 102.探索合数世纪 103.特殊要求的字符串 104.特殊整数 105.完数 106.王的对抗 107.危险的组合 108.文件比较 109.文章统计 110.五猴分桃 111.小型数据库 112.幸运儿 113.幸运数字”7“ 114.选择排序 115.寻找规律 116.循环移位 117.延伸的卡片 118.羊羊聚会 119.一维数组”赋值“ 120.一维数组”加法“ 121.勇闯天涯 122.右上角 123.右下角 124.圆及圆球等的相关计算 125.圆及圆球等相关计算 126.程序员添加行号 127.找出数字 128.找幸运数 129.找最大数 130.整数位数 131.重组字符串 132.子序列的和 133.子字符串替换 134.自然数立方的乐趣 135.字符串比较 136.字符串复制 137.字符串加密编码 138.字符串逆序 139.字符串排序 140.字符串替换 141.字符串左中右 142.组合数 143.最次方数 144.最大乘积 145.最大整数 146.最小整数 147.最长回文子串 148.左上角 149.左下角
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值