2023级西工大NOJ学习总结(附答案)

目录

4.A+B的平均值

5.进制转换

6.浮点数输出

11.倍数和​编辑

12.操作数

13.比率

15.乘数模

41.航空旅行(行李问题)

42.素数筛选法

43.稀疏矩阵

44.房价预测(线性回归)

45.蒙特卡罗方法求积分

47.回文数之和

48.货运优化

49.完美矩阵

50.前后缀移除

52.删除前后缀

54.KIDS A+B

53.分离字符串

57.字符串后缀

​编辑

58.Atol转换

​编辑

 59.大小写交换

60.元宇宙A+B

61.有效表达式

​编辑

62.循环排序

 64.Arduino显示

65.时钟A-B

66.加密字串

67.DNA双螺旋结构

68.三元搜索

69.PID控制

70.长安

71.中位数

72.热能计算

81.上楼梯

82.子数组最大和


4.A+B的平均值

注意直接算a+b如果a和b数值很大,a+b结果会溢出

正确做法:1.若a和b同号,average=(a-b)/2+b;

2.若a与b异号,直接(a+b)/2;

5.进制转换

把一个转换成8进制和16进制输出

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

通过这个题复习一下各个进制数字的表示

2进制:0b开头,如0b10101

8进制:0开头,如0756

16进制:X或x开头,如x789ff,X45FF

6.浮点数输出

本题实际考察格式化输出

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

对应课本p73

11.倍数和

#include <stdio.h>

int main(){
    unsigned int T = 0;
    unsigned int arrn[100000];
    scanf("%d", &T);
    for(unsigned int i = 0; i < T; i++){
        scanf("%u", &arrn[i]);
    }

    for(unsigned int j = 0; j < T; j++){
        unsigned int res = 0;
        for(unsigned int x = 1; x < arrn[j]; x++){
            if(x % 3 == 0 || x % 5 == 0){
                res += x;
            }
        }
        printf("%ld\n", res);
    }

    return 0;
}

12.操作数

​
#include<stdio.h>
int main()
{
	int n;
	scanf("%d",&n);
	int t=0;
	while(n>0)
	{
	    int m=n;
		//求一次n的各位数之和 
		int sum=0;
		for(int i=0;i>=0;i++)
		{
			sum+=m%10;
			m=m/10;
			if(m==0)
			break;
		}
		n-=sum;
		t++;
		
	}
	printf("%d",t);
	return 0;
}

​

13.比率

#include<stdio.h>
#include<math.h> 
//定义一个求最大公约数的函数
int gcd(int m,int n)
{
while(n)
{
int r=m%n;
m=n;
n=r;
if(r==0)
return m;
}
}

int main()
{
	double a,b;
	scanf("%lf",&a);
	b=a;
	//求a小数点后有几位 ,i表示位数 
	int i=0;
	while(a-(int)a)
	{
		a*=10;
		i++;
	}
	int u=(int)a;             
	int y=(int)pow(10,i); 
	printf("%d %d\n",u,y);
	int c=gcd(u,y);
	printf("%d/%d",u/c,y/c);
	
	return 0;
}

注意点:

1.辗转相除法求最大公约数

2.强制类型转换,浮点型转换成整形会截断(直接抛弃小数)

15.乘数模

41.航空旅行(行李问题)

#include<stdio.h>
int main()
{
	int n,a,b,c,d,e;
	scanf("%d",&n);
	int arr[n];
	for(int i=0;i<n;i++)//输入 
	{
		scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);
		if(   (a+b<=d&&c<=e) ||  (a+c<=d&&b<=e) || (b+c<=d&&a<=e)  )
		arr[i]=1; 
		else
		arr[i]=0; 
	}
	for(int j=0;j<n;j++)
	{
		if(arr[j])
		printf("YES\n");
		else
		printf("NO\n");
	}
	return 0;
 } 

1.每次输入完之后接着进行判断

2.利用数组存储每一次输入的判断结果

42.素数筛选法

#include<stdio.h>
#define N 100000000
char vis[N+1];//0表示i是素数,1表示合数 
int pr[N];
int count=0;
int Euler(int n)
{
	int i,j;
	int ans=n-1;
	for(i=2;i<=n;i++)
	{
		
		
		if(vis[i]==0)	
		pr[count++]=i;//建立一个存素数的数组 
			for(int j=0;j<count;j++)
			{
				//进行标记
				if(i*pr[j]>n) break;
				vis[i*pr[j]]=1;
				ans--;     
				if(i%pr[j]==0) break; //就是这个语句,使得每个数只被遍历一次。        
				 
			}
		
		
		
	}
	return ans; 
}
int main()
{
	int n;
	scanf("%d",&n);
	int ans=Euler(n);
	printf("%d",ans);
	return 0;
}

1.看懂埃氏筛,埃氏筛在遍历是,有多个素因子的数如12,18等会多次遍历,如果数字足够大,那么遍历的次数会大大增加。

2.欧拉筛的优点在于每一个数都只遍历一次,大大缩短了时间。

那么为什么欧拉筛的算法能遍历所有的数呢?

因为每一个合数都能分解出素因子,因此都能被遍历到。

为什么每个数都只被遍历一次呢?

打个表具体看一下

i= 2//当i取2时 
j =1 b[1] = 2 i*b[j] = 4
 
i =3//当i取3时 
j=1 b[1] = 2 i*b[j] =6
j=2 b[2] = 3 i*b[j] = 9
 
i=4//当i取4时 
j=1 b[1] = 2 i*b[j] = 8//上面提到为什么退出循环,因为如果不退出循环,就会标记一次12,所以不行
i=5//当i取5时 
j=1 b[1] = 2 i*b[j] = 10
j=2 b[2] = 3  i*b[j ]=15
j=3 b[3] = 5 i*b[j] = 25
 
i=6//当i取6时 
j=1 b[1] = 2 i*b[j] =12//这里已经标记了12了。
 
i=7//当i取7时 
j=1 b[1] = 2 i*b[j] = 14
j=2 b[1] = 3 i*b[j] = 21
j=3 b[1] = 5 i*b[j] = 35
j=4 b[1] = 7 i*b[j] = 49

每一个素数在相乘的时候,都没有乘一个大于自己的素数,这样的话,能够使12这样的数只被遍历到6时,被6*2标记一次,而不会被3*4标记,也不会被4*3标记。即总是被最小的素因子标记。

挺难理解的,想出这个方法的人真的牛。

43.稀疏矩阵

#include<stdio.h>
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	int sum=n*m;//记录非零个数 
	int arr[n][m];
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
		scanf("%d",&arr[i][j]);
		if(arr[i][j]==0)
		sum--;
	}
	 } 
	 double all=(double)(m*n);
	 if( sum/all<=0.05 || (sum==m) || (sum==n)) 
	 printf("Yes");
	 else
	 printf("No");
	 
	return 0;
}

没啥好说的,重点可能就时二维数组的应用。

44.房价预测(线性回归)

#include<stdio.h>
int main()
{
	//输入 
	int n;
	double sum_x=0.0,sum_y=0.0;
	int sqr_x; 
	int xy=0; 
	int y[100],x[100];
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d %d",&x[i],&y[i]);
		sum_x+=x[i];
		sum_y+=y[i];
		xy+=x[i]*y[i]; 
		sqr_x+=x[i]*x[i];
	}
	//计算平均值 
	double avg_x=sum_x/n;
	double avg_y=sum_y/n;
	//带入公式计算最终结果 
	double b=(xy-n*avg_x*avg_y)/(sqr_x-n*avg_x*avg_x);
	double a=avg_y-b*avg_x;
	if(b>0)
	printf("Y=%.4lf+%.4lf*X",a,b);
	else
	printf("Y=%.4lf%.4lf*X",a,b);
	return 0; 
}

简单题。

45.蒙特卡罗方法求积分

#include<stdio.h>
#include<math.h>
#include<stdlib.h> 
double fun1(double x); 
double fun2(double x); 
double fun3(double x); 
double fun4(double x); 
double fun5(double x); 
int main()
{
	srand(RAND_MAX);
	double (*fun[6])(double)={0,fun1,fun2,fun3,fun4,fun5};//函数指针数组 
	int m,n;
	double a,b,sum;
	scanf("%d %lf %lf %d",&m,&a,&b,&n);
	for(int i=1;i<=n;i++)
	{
		double r= ((double)rand() / RAND_MAX) * (b-a)+ a;;//把生成的随机数转化成a,b之间的数 
		double y=fun[m](r);
		sum+=y*(b-a);
	 } 
	 printf("%.6lf",sum/n);
	return 0;
}
double fun1(double x)
{
	double a=exp(-x);
	return x*x*x*x*a;
}
double fun2(double x)
{
	return x*x+1;
}
double fun3(double x)
{
	return cos(x);
}
double fun4(double x)
{
	return sqrt(x)*(x-2);
}
double fun5(double x)
{
	return 2*sin(x)-5*cos(x);
}












47.回文数之和

#include<stdio.h>
int Palindromic_num_10(int n);//判断是不是 10进制回文数
int Palindromic_num_k(int n,int k); //判断是不是k进制回文数 
int main()
{
	int n,k;
	int sum=0;
	scanf("%d %d",&n,&k);
	for(int i=1;i<n;i++)
	{
		if(Palindromic_num_10(i)&&Palindromic_num_k(i,k))
		sum+=i;
	}
	printf("%d",sum);
	return 0;
}
int Palindromic_num_10(int n)
{
	//取n的每一位 
	int arr[100];
	int i;
	for( i=0;n>0;i++)
	{
		arr[i]=n%10;
		n/=10;
	}
	int left=0;
	int right=i-1;
	while(left<right)
	{
		if(arr[left]==arr[right])
		{
			left++;
			right--;
		}
		else
		return 0;
	}
	return 1;
}
int Palindromic_num_k(int n,int k)
{
	//取n转化成k进制的数的每一位,用取余的方法
	int arr[100];
	int i;
	for( i=0;n>0;i++)
	{
		arr[i]=n%k;//注意,这里先取到的是高位 
		n/=k;
	 } 
	 int left=0;
	 int right=i-1;
	 while(left<right)
	 {
	 	if(arr[left]==arr[right])
	 	{
	 		left++;
	 		right--;
		 }
	 	else
	 	return 0;
	 }
	 return 1;
	 
}

学会用取余的方法把一个数转化成其他进制的数。

48.货运优化

#include<stdio.h>
int main()
{
	int ans[1000];
	int n=0;
		while(1)
	{
		int sum=0;
		int arr[7]={0};
		for(int i=1;i<=6;i++)
		{
			scanf("%d",&arr[i]);
			sum+=arr[i]; 
		}
		if(sum==0)
		break;//如果全为0就退出循环
		 ans[n]=arr[4]+arr[5]+arr[6]+(arr[3]+3)/4;//+3是起到向上取整的效果 
		 //4 5 6必定会占一个箱子,4个3占一个箱子,多余的必定也占一个箱子 
	     //对4 和 3 补2 
		 int consume[4]={0,5,3,1};
		 int total_con2=arr[4]*5+consume[arr[3]%4];//代表消耗2的量 
		 int esp=arr[4]*20+arr[5]*11+36-9*(arr[3]%4);//esp代表3,4,5装完之后空出的空间
		 if(arr[2]>total_con2)
		 {
		 arr[2]-=total_con2;
		 ans[n]+=(arr[2]+8)/9;
		 esp-=total_con2*4+36-(arr[2]%9)*4;
	     }
		 else
		 {
		 	esp-=arr[2]*4;
		 	arr[2]=0;
		  } 
		  //剩余的空间补1
		  if(arr[1]>esp)
		  ans[n]+=(arr[1]-esp)/36; 
		  n++;
		
	}
	for(int j=0;j<n;j++)
	{
		printf("%d\n",ans[j]);
	}
	
	
	return 0;
}

49.完美矩阵

#include<stdio.h>
#include<math.h>
int arr[301][301];
int getsum(int i,int j,int k)
{
	int sum=0;
	for(int b=i+1;b<i+k;b++)
	{
	for(int a=j+1;a<j+k;a++)
	{
		sum+=arr[b][a];
	}
   }
   return sum;
}
int main()
{
	int n,m;
	int ans=0;//记录结果 
	scanf("%d %d",&n,&m);
		//输入 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&arr[i][j]);
			if(arr[i][j]==0)
			arr[i][j]=-1;
		}
	}
	//
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			for(int k=1;k+i<=n&&k+j<=m;k++)//设置一个基点,从这个点向右向下拓展,即可做到不重不漏 
			{
				if(arr[i][j]==-1||arr[i+k][j]==-1||arr[i][j+k]==-1)//只要上边和左边有一个
				break;                                       //数是0,那么就直接换下一个基点
				else
				{
					for(int p=j+1;p<=j+k;p++)
					{
						if(arr[i+k][p]==-1)
						  goto break_;
					}
					for(int q=i+1;q<=i+k;q++)
					{
						if(arr[q][j+k]==-1)
						goto break_;
					}
					if(k>2)
					{
						if(abs(getsum(i,j,k))>1)
						continue;
					}
						ans++; 
					break_:;
				
					
				}
			}
		}
	}
	
		printf("%d",ans);
	return 0;
}

这题主要考验思维,能不能想到从一个基点开始遍历。并且要想到减小运算的方法。

50.前后缀移除

#include<stdio.h>
#include<string.h>
void str_lstrip(char* str,char* dele)
{
	int move=0; 
	for(int i=0;i<strlen(str);i++)
	{
		if(strchr(dele,str[i]))//在dele中搜索有没有str[i],有返回地址,没有返回null 
		{
			move++;
		}
		else
		break;
	}
	memmove(str,str+move,strlen(str)-move+1);
}
void str_rstrip(char* str,char* dele)
{
	int move=0; 
	for(int i=strlen(str)-1;i>=0;i--)
	{
		if(strchr(dele,str[i]))
		{
			move++;
		}
		else
		break;
	}
	char* p=str+strlen(str);//指向字符串的\0 
	memmove(p-move,p,1);
}
int main()
{
	char str[1000]="";
	char dele[1000]="";
	char str2[1000]="";
	scanf("%[^\n]",str);
	getchar();
	scanf("%[^\n]",dele);
	strcpy(str2,str);
	str_lstrip(str,dele);
	printf("%s\n",str);
	str_rstrip(str2,dele);
	printf("%s\n",str2);
	str_rstrip(str,dele);
	printf("%s",str);
	return 0;
}

52.删除前后缀

#include<stdio.h>
#include<string.h>
void remove_prefix(char* str,char* dele)
{
	char* p=str;
	int move=0;
	while(*p==dele[0])
	{	
	for(int i=1;i<strlen(dele);i++)
	 {
         if(p[i]!=dele[i])
		 goto a;       		
	 }
	 p+=strlen(dele);
	 move+=strlen(dele);
   }
   a:
   	memmove(str,str+move,strlen(str)-move+1);
}

void remove_suffix(char* str,char* dele)
{
	char* p=str+strlen(str);//指示\0
	char* dest=str+strlen(str)-1;//指示最后一个
	int destination=strlen(str);
	while(*dest==dele[strlen(dele)-1])
	{
		dest--;
		for(int i=strlen(dele)-2;i>=0;i--,dest--)
		{
			if( (*dest) !=dele[i])                                                                 
			goto a;
		}
		destination-=strlen(dele);
	 }
	 a: 
	    str[destination]='\0';
}
int main()
{
	char str[1000]="";
	char dele[1000]="";
	char str2[1000]="";
	scanf("%[^\n]",str);
	getchar();
	scanf("%[^\n]",dele);
	strcpy(str2,str);
	remove_prefix(str,dele);
	printf("%s\n",str);
	remove_suffix(str2,dele);
	printf("%s",str2);
	return 0;
}

54.KIDS A+B

#include<stdio.h>
#include<string.h>
int strtoint(const char*numbers[],char A[])
{
	for(int i=0;i<=99;i++)
	{
		if(strcmp(A,numbers[i])==0)
		return i;
	}
}
int main()
{
	 const char* numbers[100] = {  
        "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",  
        "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen",  
        "twenty", "twenty-one", "twenty-two", "twenty-three", "twenty-four", "twenty-five", "twenty-six", "twenty-seven", "twenty-eight", "twenty-nine",  
        "thirty", "thirty-one", "thirty-two", "thirty-three", "thirty-four", "thirty-five", "thirty-six", "thirty-seven", "thirty-eight", "thirty-nine",  
        "forty", "forty-one", "forty-two", "forty-three", "forty-four", "forty-five", "forty-six", "forty-seven", "forty-eight", "forty-nine",  
        "fifty", "fifty-one", "fifty-two", "fifty-three", "fifty-four", "fifty-five", "fifty-six", "fifty-seven", "fifty-eight", "fifty-nine",  
        "sixty", "sixty-one", "sixty-two", "sixty-three", "sixty-four", "sixty-five", "sixty-six", "sixty-seven", "sixty-eight", "sixty-nine",  
        "seventy", "seventy-one", "seventy-two", "seventy-three", "seventy-four", "seventy-five", "seventy-six", "seventy-seven", "seventy-eight", "seventy-nine",  
        "eighty", "eighty-one", "eighty-two", "eighty-three", "eighty-four", "eighty-five", "eighty-six", "eighty-seven", "eighty-eight",  "eighty-nine",  
        "ninety","ninety-one","ninety-two","ninety-three","ninety-four","ninety-five","ninety-six","ninety-seven","ninety-eight","ninety-nine"
    }; 
    char A[20];
    char B[20];
    scanf("%s",A);
    getchar();
    scanf("%s",B);
    int a=strtoint(numbers,A);
    int b=strtoint(numbers,B);
    printf("%s",numbers[a+b]);
    
	return 0;
}

53.分离字符串

#include<stdio.h>
#include<string.h>
int str_split(char ans[][100],char str[],char sep[])
{
	int len=strlen(sep);
	int start=0,end=0;
	int a=0;//记录有几个断点 
	for(int i=0;i<strlen(str);i++)
	{
		int flag=0;//判断是不是断点的标志 
		if(str[i]==sep[0])
		{
			for(int j=1;j<len;j++)
			{
				if(str[i+j]!=sep[j])
				break;
				flag++;
			}
			if(flag==len-1)//找到断点 
			{
				end=i-1;
				int p=0;
				for( int k=start;k<=end;k++)
				{
				    ans[a][p]=str[k];
				    p++;
			    }
			    if(i!=0)//防止上来就是断点而打印一个换行 
				{
				for(int o=0;o<p;o++)
			    printf("%c",ans[a][o]);
			    printf("\n");
			    }
			    start=i+len;
			    a++;
			   
			}		
		}
		if((i==strlen(str)-1)&& start<strlen(str))//使最后一个断点之后的能得到打印,并且避免断点出现在最后的时候重复打印 
			{
				int p=0;
				for(int k=start;k<=i;k++)
				{
				    ans[a][p]=str[k];
				    p++;
			    }
			    for(int o=0;o<p;o++)
			    printf("%c",ans[a][o]);
			}
	}
	return a+1;
}
int main()
{
	char str[1000];
	char sep[200];
	char ans[20][100]; 
	scanf("%[^\n]",str);
	getchar(); 
	scanf("%[^\n]",sep);
	str_split(ans,str,sep);
	return 0;
}

57.字符串后缀

#include<stdio.h>
#include<string.h>
int str_endswith(char str[],char suffix[]);
int main()
{
	char str[1000];
	char suffix[1000];
	scanf("%[^\n]",str);
	getchar();
	scanf("%[^\n]",suffix);
	if(str_endswith(str,suffix))
	printf("Yes");
	else
	printf("No");
	return 0;
}
int str_endswith(char str[],char suffix[])
{
	for(int i=0;i<strlen(str);i++)
	{
		if(str[i]==suffix[0])
		{
			int flag=0;
			for(int j=1;j<strlen(suffix);j++)
			{
				if( str[i+j]!=suffix[j])
				 break;
				 flag++;
			}
			if(flag==strlen(suffix)-1 && strlen(str)-strlen(suffix)==i) 
			return 1;
		}
	}
	return 0;
}

58.Atol转换

#include <stdio.h>
#include <limits.h>
 
int atol(char *str) {
    char *pStr = str;
    int sgn = 1;
    long long tmp = 0;
    if (*pStr == '+') ++pStr;
    else if (*pStr == '-') sgn = -1, ++pStr;
 
    while (*pStr) {
        if (*pStr == ' ') ;
        else if ('0' <= *pStr && *pStr <= '9') {
            tmp = (*pStr - '0') + tmp * 10;
            if ((tmp * sgn) >= INT_MAX) return INT_MAX;
            else if ((tmp * sgn) <= INT_MIN) return INT_MIN;
        }
        else break;
        ++pStr;
    }
    return tmp * sgn;
}
 
int main() {
    char str[1000] = "";
    scanf("%[^\n]", str);
    printf("%d", atol(str));
    return 0;
}

 59.大小写交换

#include<stdio.h>
#include<string.h> 
void str_swapcase(char arr[])
{
	for(int i=0;i<strlen(arr);i++)
	{
		if(arr[i]<=90 && arr[i]>=65)//大写字母
		arr[i]=arr[i]+32;
		else if(arr[i]>=97 && arr[i]<=122)
		arr[i]=arr[i]-32;
		 
	}
}
int main()
{
	char arr[100];
	scanf("%[^\n]",arr);
	str_swapcase(arr);
	printf("%s",arr);
	return 0;
}

60.元宇宙A+B

#include<stdio.h>
#include<string.h>
char num[36] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
                  'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
                  'U', 'V', 'W', 'X', 'Y', 'Z'};
int strtoint(char a)
 {
    int ans = 0; 
    if ( a >= '0' && a <= '9')
    ans=a-'0';
    else if(a>='A' && a<='Z')
    ans=10+a-'A';
    return ans;
}
int add(char* arr1,char* arr2,int m,char* ans)//返回最后一个元素的下标 
{
	int Cin=0;
	int j=0;
	for(int i=m-1;i>=0;i--)
	{
	  int  a=strtoint(arr1[i])+strtoint(arr2[i]);
	  if(a<36)
	  {
	  	ans[j]=num[a+Cin];
	  	Cin=0;
	  }
	  else
	  {
	  	ans[j]=num[a-36+Cin];
	  	Cin=1;
	  }
	  j++;
	}
	if(Cin==1)
	{
		ans[j]=num[1];
		return j;
	}
	return j-1;
}
int main()
{
    char arr1[1000];
    char arr2[1000];
    char ans[1000];
    scanf("%s", arr1);
    getchar();
    scanf("%s", arr2);
    int len1=strlen(arr1);
    int len2=strlen(arr2);
	//对齐操作
    if(len1<len2)
    {
    	int n=len2-len1;
    	memmove(arr1+n,arr1,strlen(arr1));
    	for(int i=0;i<n;i++)
    	{
    		arr1[i]='0';
		}
	}
	else if(len1>len2)
	{
		int n=len1-len2;
		memmove(arr2+n,arr2,strlen(arr2));
		for(int i=0;i<n;i++)
    	{
    		arr2[i]='0';
		}
	}
	//相加
	int m=len1>len2?len1:len2;
	int x=add(arr1,arr2,m,ans);
	//输出 
	for(int i=x;i>=0;i--)
	{
		printf("%c",ans[i]); 
	}
	return 0;
}

61.有效表达式

#include<stdio.h>
typedef long long int ll;
long long int C(int a,int b)//求组和数 
{
	ll x=1,y=1,z=1;
	for(int i=2;i<=a;i++)
	{
		x*=i;//a的阶乘 
	}
	for(int i=2;i<=b;i++)
	{
		y*=i;//b的阶乘 
	}
	for(int i=2;i<=a-b;i++)
	{
		z*=i;//a-b的阶乘 
	}
	return x/(z*y);
}
int main()
{
	int n;
	scanf("%d",&n);
	ll ans=C(2*n,n)-C(2*n,n+1); //具体推导请搜索 卡特兰数 
	printf("%lld",ans); 
	return 0;
}

62.循环排序

#include <stdio.h>
 
void swap(int *a, int *b) {
	int tmp = *a;
	*a = *b, *b = tmp;
}
 
void cycleSort(int arr[], int n) {
	for (int i = 0; i < n - 1; ++i) {
		int item = arr[i], pos = i;
		for (int j = i + 1; j < n; ++j) if (arr[j] < item) ++pos;
		if (pos == i) continue;
 
		swap(&arr[pos], &item);
		while(pos != i) {
			pos = i;
			for (int j = i + 1; j < n; ++j) if (arr[j] < item) ++pos;
			while (item == arr[pos]) ++pos;
			swap(&arr[pos], &item);
		}
	}
}
 
int main() {
	int n;
	scanf("%d", &n);
	int arr[n];
	for (int i = 0; i < n; ++i) scanf("%d", &arr[i]);
	cycleSort(arr, n);
	for (int i = 0; i < n; ++i) printf("%d ", arr[i]);
	return 0;
}

 64.Arduino显示

#include<stdio.h>
int main()
{
	int n;
	scanf("%d",&n);
	int ans=0;
	int flag=0;
	int arr[100]={6,2,5,5,4,5,6,3,7,6};
	for(int i=10;i<=99;i++)
	{
		int t=i;
		while(t)
		{
			arr[i]+=arr[t%10];
			t/=10;
		}
	}
	for(int i=0;i<=99;i++)
	{
		for(int j=0;j<=99;j++)
		{
			if( arr[i]+arr[j]+arr[i+j]==n-4  &&  i+j<100)
			ans++;
			else
			continue;
			if(i==j)
			flag++;
		}
	}
	ans-=flag/2;
	printf("%d",ans);
	return 0;
}

65.时钟A-B

#include<stdio.h>
#include<time.h>
int main()
{
	struct tm timeA,timeB;
	scanf("%d %d %d %d %d %d",&timeA.tm_year,&timeA.tm_mon,&timeA.tm_mday,&timeB.tm_year,&timeB.tm_mon,&timeB.tm_mday);
    //time_t ans=(time_t)mktime(&timeA)-(time_t)mktime(&timeB);
    // 调整日期的格式
    timeA.tm_year -= 1900;
    timeA.tm_mon -= 1;
    timeB.tm_year -= 1900;
    timeB.tm_mon -= 1;
    // 设置时间为0点
    timeA.tm_hour = 0;
    timeA.tm_min = 0;
    timeA.tm_sec = 0;
    timeB.tm_hour = 0;
    timeB.tm_min = 0;
    timeB.tm_sec = 0;
    time_t time1=mktime(&timeA);
    time_t time2=mktime(&timeB);
    double ans = difftime(time1, time2);
   // printf("%ld\n",time1);
    printf("%.6lf",ans);
	return 0;
}

66.加密字串

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[100];
	int x;
	scanf("%s",arr);
	scanf("%d",&x); 
	char ans[100];
	strcpy(ans,arr);
	int n=strlen(arr);
	int flag=0;
	for(int i=0;i<n;i++)
	{
		flag=0;
		for(int j=0;j<n;j++)
		{
			if(arr[j]==ans[i])
			flag++;
		}
		if(flag&1)   
		{
			ans[i]-=x;
			if(ans[i]<'a')
			ans[i]+=26;
			else if(ans[i]>'z')
			ans[i]-=26;
		 } 
		 else
		 {
		 	ans[i]+=x;
		 	if(ans[i]<'a')
			ans[i]+=26;
			else if(ans[i]>'z')
			ans[i]-=26;	
		 }
	}
	printf("%s",ans);
	return 0;
}

67.DNA双螺旋结构

#include<stdio.h>
void print1()
{
	printf("   AT\n");
	printf("  T--A\n");
	printf(" A----T\n");
	printf("T------A\n");
}
void print2()
{
	printf("T------A\n");
	printf(" G----C\n");
	printf("  T--A\n");
	printf("   GC\n");
}
void print3()
{
	printf("   CG\n");
	printf("  C--G\n");
	printf(" A----T\n");
	printf("A------T\n");
}
void print4()
{
	printf("T------A\n");
	printf(" A----T\n");
	printf("  A--T\n");
	printf("   GC\n");
}
void print5()
{
	printf("   AT\n");
	printf("  C--G\n");
	printf(" T----A\n");
	printf("C------G\n");
}
void print6()
{
	printf("C------G\n");
	printf(" T----A\n");
	printf("  G--C\n");
	printf("   AT\n");
}

int main()
{
	void(*p[6])()={print1,print2,print3,print4,print5,print6};
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		int t=i%6;
		p[t]();
	}
	return 0;
}

68.三元搜索

#include<stdio.h>
int Ternary_search(int *arr,int n,int key)
{
	int left=0;
	int right=n-1;
	int mid1,mid2;
	while(mid1<=mid2)
	{
		mid1=left+(right-left)/3;
		mid2=right-(right-left)/3;
		if(key==arr[mid1])
		return mid1;
		else if(key==arr[mid2])
		return mid2;
		else if(key<mid1)
		right=mid1-1;
		else if(key>arr[mid2])
		left=mid2+1;
		else
		{
			left=mid1+1;
			right=mid2-1;
		}
	}
	return -1;
}

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

69.PID控制

#include<stdio.h>
typedef struct PIDController
{
	double Kp,Ki,Kd;//比例,积分,微分系数
	double preError,integral;//前次误差,积分 
}PID; 
double PIDCalculate(PID* pid,double setpoint,double measuredValue)
{
	double error=setpoint-measuredValue;
	pid->integral+=error;
	double a=error-pid->preError;
	double output=pid->Kp*error+pid->Ki*pid->integral+pid->Kd*a;
	pid->preError=error;
	return output;
}
int main()
{
	PID p;
	PID* pid=&p;
	double setpoint,measuredValue;
	pid->preError=0;
	pid->integral=0;
	scanf("%lf %lf %lf",&pid->Kp,&pid->Ki,&pid->Kd);
	scanf("%lf %lf",&setpoint,&measuredValue);
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		measuredValue+=PIDCalculate(pid,setpoint,measuredValue);
		printf("%d %.6lf\n",i,measuredValue);
	}
	return 0;
}

70.长安

#include<stdio.h>
int C(int a,int b)//求组和数 
{
	int x=1,y=1,z=1;
	for(int i=2;i<=a;i++)
	{
		x*=i;//a的阶乘 
	}
	for(int i=2;i<=b;i++)
	{
		y*=i;//b的阶乘 
	}
	for(int i=2;i<=a-b;i++)
	{
		z*=i;//a-b的阶乘 
	}
	return x/(z*y);
}
int main()
{
	int bx;
	int by;
	int px;
	int py;
	//输入
	for(int i=0; ;i++)
	{
		scanf("%d %d %d %d",&bx,&by,&px,&py);
		if(bx<=0 || by<=0 || px<=0 || py<=0)
		break;
		else
		{
			if(bx>=px && by>=py)
			{
			int ans=C(bx+by-2,bx-1)-C(px+py-2,px-1)*C(bx+by-px-py,bx-px);
			printf("%d\n",ans);
		    }
		    else
		    {
		    int ans=C(bx+by-2,bx-1);
			printf("%d\n",ans);
		    	
			}
		}
	 } 
	return 0;
}

71.中位数

#include<stdio.h>
int main()
{
	int arr[1000];
	double mid[100];
	int len[100];
	int judge;
	int m=0;
	for(int i=0; ;i++)
	{
		scanf("%d",&judge);
		if(judge>0)
		arr[i]=judge;
		else if(judge==0)
		{
			i--;
			len[m]=i;//记录一组数据最大的下标
			if(i&1)//偶数个数据,总共i+1个数 
			mid[m]=(arr[i/2]+arr[i/2+1])/2.0;
			else
			mid[m]=(double)arr[i/2];
			m++;//最终一共有m组数据 
			continue;
		}
		else if(judge<0)
		break;
	}
	//print
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<=len[i];j++)
		{
			printf("%d ",arr[j]);
		 } 
		 printf("%.6lf\n",mid[i]);
	 } 
	return 0;
}

72.热能计算

#include<stdio.h>
int main()
{
	int Ti,Tf;
	double ml,mr,cl,cr;//liquid,container 
	scanf("%d %d",&Ti,&Tf);
	scanf("%lf %lf",&ml,&cl);
	scanf("%lf %lf",&mr,&cr);
	double a=ml*cl+mr*cr;
	double Q=a*(Tf-Ti);
	double Qlp=(ml*cl)/a;
	double Qrp=(mr*cr)/a;
	printf("%.2lfkJ,%.2lf%%,%.2lf%%",Q/1000,Qrp,Qlp);
	return 0;
 } 

81.上楼梯

#include<stdio.h>
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	int dp[n+1][2];
	dp[0][0]=1;
	dp[1][0]=1;
	for(int i=0;i<=n;i++)
	{
		dp[i][1]=0;
	}
	for(int i=0;i<m;i++)
	{
		int p;
		scanf("%d",&p);
		dp[p][1]=1;
		if(p==1)
		dp[1][0]=0;
	}
	for(int i=2;i<=n;i++)
	{
		if(dp[i][1])
		dp[i][0]=0;
		else
		{
			dp[i][0]=(dp[i-1][0]+dp[i-2][0])%1000000007;
		}
	}
	printf("%d",dp[n][0]);
	return 0;
}

82.子数组最大和

#include<stdio.h>
int main()
{
	int arr[1000];
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&arr[i]);
	}
	int start=arr[0];
	int max=0;
	int sum=arr[0];
	for(int i=1;i<n;i++)
	{
		sum+=arr[i];
		if(sum<arr[i])//如果加到arr[i]的数还不如arr[i]大,说明从i开始更好 
		sum=arr[i];
		if(sum>max)
		max=sum; 
	}
	printf("%d",max);
	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.左下角
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值