第13周总结

1.谁拿了最多奖学金(JSU-ZJJ)

题目描述

某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:

  1)  院士奖学金,每人8000元,期末平均成绩高于80分(>80),并且在本学期内发表1篇或1篇以上论文的学生均可获得;

  2)  五四奖学金,每人4000元,期末平均成绩高于85分(>85),并且班级评议成绩高于80分(>80)的学生均可获得;

  3)  成绩优秀奖,每人2000元,期末平均成绩高于90分(>90)的学生均可获得;

  4)  西部奖学金,每人1000元,期末平均成绩高于85分(>85)的西部省份学生均可获得;

  5)  班级贡献奖,每人850元,班级评议成绩高于80分(>80)的学生干部均可获得;

  只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如姚林的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。

  现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的条件)。

输入

每组测试数据的输入的第一行是一个整数N(1 <= N <= 100),表示学生的总数。接下来的N行每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。姓名是由大小写英文字母组成的长度不超过20的字符串(不含空格);期末平均成绩和班级评议成绩都是0到100之间的整数(包括0和100);是否是学生干部和是否是西部省份学生分别用一个字符表示,Y表示是,N表示不是;发表的论文数是0到10的整数(包括0和10)。每两个相邻数据项之间用一个空格分隔。

输出

输出包括三行,第一行是获得最多奖金的学生的姓名,第二行是这名学生获得的奖金总数。如果有两位或两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。第三行是这N个学生获得的奖学金的总数。

样例输入 复制

4
YaoLin 87 82 Y N 0
ChenRuiyi 88 78 N Y 1
LiXin 92 88 N N 0
ZhangQin 83 87 Y N 1

样例输出 复制

ChenRuiyi
9000
28700
#include //谁拿最多奖学金
#include 
#include 
#include 
int main()
{
	int t,qmcj[101],py[101],lw[101]={0},sum[101]={0},mans=0;//分别为期末成绩,评议成绩,论文数量,个人总奖学金,所有学生奖学金
	char a[101][21],gb[101],xb[101];//分别为名字,干部,西部
	while(~scanf("%d",&t))//多组输入(t为学生的个数)
	{
		memset(sum,0,sizeof(sum));//初始化
		mans=0;//初始化
		for(int i=0;i80&&lw[i]>=1)sum[i]+=8000;
			if(qmcj[i]>85&&py[i]>80)sum[i]+=4000;
			if(qmcj[i]>90)sum[i]+=2000;
			if(qmcj[i]>85&&xb[i]=='Y')sum[i]+=1000;
			if(py[i]>80&&gb[i]=='Y')sum[i]+=850;
			mans+=sum[i];
		}
		int name=0;//擂主
		int max=sum[0];//擂主
		for(int i=1;imax){
				max=sum[i];
				name=i;
			}
		}
		printf("%s\n",a[name]);
		printf("%d\n",max);
		printf("%d\n",mans);//所有学生总成绩
	}	
}

2.写几个函数:

①输入10个职工的姓名和职工号;

②按职工号由小到大顺序排列,姓名顺序也随之调整;

③要求输入一个职工号,用折半查找找出该职工的姓名,从主函数输入要查找的职工号,输出该职工姓名。

#include 
#include 
#include 
#include 
//定义一个结构体储存名字和学号
struct stu
{
	char name[100];//名字的字符数组
	int xh;
};	
struct stu a[10];//十个职宫
struct stu temp;
//排序函数//对结构体进行排序
int px()
{
	for(int i=0;i<10;i++)
	{
		scanf("%s %d",a[i].name,&a[i].xh);//对应职工的名字成绩的录入
	}
		//选择排序//对整个结构体进行排序
	for(int i=0;i<9;i++)
	{
		for(int j=i+1;j<10;j++)
		{
			if(a[i].xh>a[j].xh)
			{
				temp=a[i];//利用temp结构体交换结构体
				a[i]=a[j];
				a[j]=temp;
			}
		}
	}
}
int zbcz(int temp1)//折半查找输入的职工
{
	int left = 0;
	int right = 9;
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (a[mid].xh > temp1){
			right = mid - 1;
		}
		else if (a[mid].xh < temp1){
		   left = mid + 1;
		}
		else{
			printf("在第%d位\n", mid+1);
			printf("name:%s",a[mid].name);
			//找到了
			break;
		}
    }
	if (left > right)//找不到
	{
		printf("找不到了\n");
	}
}
int main()
{
	int number;
	px();
	scanf("%d",&number);
	zbcz(number);
	return 0;
}

3.用牛顿迭代法求根。方程为apow(x,3)+bpow(x,2)+cx+d系数a,b,c,d的值由主函数输入,分别为1,2,3,4。求x在1附近的一个实根。求出根后由主函数输出.

#include 
#include 
#include 
#include 
int diedai(int a,int b,int c,int d)
{
	double x1=1,x2,a1,a2;
	while(fabs(x1-x2)>=1e-5)
	{
	    x2=x1;
	    a1=((a*x2-b)*x2+c)*x2-d;
	    a2=(3*a*x2-2*b)*x2+c;
	    x1=x2-a1/a2;
	}
	printf("%f",x1);
}
int main()
{
	int a,b,c,d;
    scanf("%d %d %d %d",&a,&b,&c,&d);
    diedai(a,b,c,d);
    return 0;
}

4. 数学黑洞

问题描述】

任给一个4位正整数,其各位数位上的数字不全相同,将数字重新组合成一个最大的数与最小的数相减,重复这个过程,最多7步,必得6174。对任给的4位正整数(各位数位上的数字不全相同),编程输出掉进黑洞的步数。

【输入】

一行,一个4位正整数n(1000< n<9999)

【输出】

掉进黑洞的步数

输入

1234

输出

3

#include //数学黑洞
#include 
#include 
#include 
int cmp1(const void *p1,const void *p2)//升序
{
	return(*(int*)p1-*(int*)p2);
}
int cmp2(const void *p1,const void *p2)//降序
{
	return(*(int*)p2-*(int*)p1);
}
//将各个位的数字组合为整数
int zqu(int *p)
{
	int ans=p[0]+p[1]*10+p[2]*100+p[3]*1000;//4位数的位数结合//n位数的话采用循环进行结合
	return ans;
}
//分解位数的函数
int fj(int n,int *p)
{
	int cnt=0;
	while(n)
	{
		p[cnt++]=n%10;
		n/=10;
	}
}
int main()
{
	int num,cnt=0;
	int a[4];
	scanf("%d",&num);//输入数字
	while(num!=6174)
	{	
		fj(num,a);//分解到数组a中
		qsort(a,4,sizeof(a[0]),cmp1);//对其进行排序升序
		int max=zqu(a);//求出该整数
		qsort(a,4,sizeof(a[0]),cmp2);//对其进行排序降序
		int min=zqu(a);//求出该整数
		num=max-min;//
		cnt++;//次数++
	}
	printf("%d",cnt);
	return 0;
	
}

5.数字拆分

题目描述

给定一组整数 l 和 r,(1 <= l <= r <= 100000), 再给定一个整数 t (0 <= t <= 9),求 [l, r] 之间的数的十进制表示中会出现多少个 t。

输入

输入三个整数 l ,r,t。

输出

输出一个整数表示有多少个 t。

样例输入 复制

1 11 1

样例输出 复制

4
#include 
#include 
#include 
#include //数字拆分
int fj(int n,int *p)
{
	int cnt=0;
	while(n)
	{
		p[cnt++]=n%10;//将数字拆分后存储到数组中
		n/=10;
	}
}
int a[10000001];
int main()
{
	memset(a,-1,sizeof(a));//数组元素全部初始化为-1
	int l,r,t,i,cnt=0;
	scanf("%d%d%d",&l,&r,&t);//区间的输入
	for(i=l;i<=r;i++)//循环从区间开始
	{
		fj(i,a);//对循环到的数进行拆分
		for(int j=0;a[j]!=-1;j++)//遍历数组假如出现和t相同的就cnt++
		{
			if(a[j]==t)cnt++;
		}
	}
	printf("%d",cnt);//输出个数
	return 0;
	
}

 6.直接插入排序

题目描述

利用直接插入排序算法实现线性表的排序。要求输出第k趟排序的结果。例如原来线性表为:26,12,25,4,36,15,21,第一趟直接排序排序结果为: 12,26,25,4,36,15,21,第二趟直接插入排序结果为: 12,25,26, 4,36,15,21。

输入

输入包含若干个测试用例,第一行为测试用例个数。每个测试用例占3行,第一个为元素个数n(1<=n<=1000),第二行为n个元素值(整数),即需要排序的元素个数,第三行为k(1<=k<=n-1),即要求的第k趟排序结果。

输出

对每一测试用例,用一行输出第k趟排序结果,用空格隔开。

样例输入 复制

1
5
2 4 1 9 7
3

样例输出 复制

1 2 4 9 7
#include 
#include 
#include //直接插入排序
#include 
int main()
{
	int i,j,t,n,a[1002],min,k;
	scanf("%d",&t);//t组数据
	for(int f=1;f<=t;f++)
	{
		scanf("%d",&n);//n个数字
		for(j=0;j=0&&min

7. Cool Number

题目描述

对于一个数大于等于0的数X,我们定义三个函数,g1(x),g2(x),f(x)
g1(x) = 让x的所有数字从大到小排列(比如123变成321)
g2(x) = 让x的所有数字从小到大排列(比如321变成123)
f(x) = g1(x) - g2(x)
我们给定两个数N和K,让你算出N,f(N)经过K次运算后是多少?

 

输入

第一行输入两个数N(1<=N<=1e9),K(1<=k<=1e5)

输出

一个数f(N)

样例输入 复制

314 2

样例输出 复制

693

 分析发现和数字黑洞很像,因此代码注释不再赘述 

#include 
#include 
#include 
#include 
int cmp1(const void *p1,const void *p2)
{
	return(*(int*)p1-*(int*)p2);
}
int cmp2(const void *p1,const void *p2)
{
	return(*(int*)p2-*(int*)p1);
}
int fj(int *p,int k)//数字分解的函数
{
	int i=0;
	while(k!=0)
	{
		p[i++]=k%10;
		k/=10;
	}
	return i;//返回位数
}
int sum(int *p,int n)//数字组合的函数
{
	int ans=1;
	for(int i=0;i

8.好事成双 

题目描述

不得不说学姐真是个博学的人,她非常喜欢阅读成语词典,这天她看到了一个词”好事成双“,于是她决定拿来靠靠学弟学妹们。
学姐给你一个序列a = (A1, A2,…), AN)长度为N,由非负整数组成。确定是否有一个偶数表示为a的两个不同元素的和,如果存在,找出最大的偶数。

输入

第一行一个N
第二行N个数

输出

如果没有表示为a的两个不同元素的和的偶数,则输出-1。如果存在这样的偶数,则输出最大的偶数。

样例输入 复制

3
2 3 4

样例输出 复制

6

提示

  • 2≤N≤2×105
  • 0≤Ai≤109
    #include 
    #include 
    #include 
    #include 
    int a[200005];int b[200005];
    int cmp(const void *p2,const void *p1)
    {
    	return(*(int*)p1-*(int*)p2);
    }
    int isos(int n)
    {
    	if(n%2==0)return 1;//偶数
    	return 0;//奇数
    }
    int main()
    {
    	int n,temp,cnt1=0,cnt2=0;
    	scanf("%d",&n);//n个数的输入
    	for(int i=0;i=2||cnt1>=2)//此处的条件是重点//认真分析题目,假如有俩个奇数或者有俩个偶数说明一定可以组成一个偶数
        {
            qsort(a,cnt1,sizeof(a[0]),cmp);//升序排列录入a数组的偶数
            qsort(b,cnt2,sizeof(b[0]),cmp);//升序排列录入a数组的奇数
            printf("%d",a[0]+a[1]>b[0]+b[1]?a[0]+a[1]:b[0]+b[1]);//将最大的俩个的和进行比较
        }
        else printf("-1");
    }

    9.a%b

  • 题目描述给定一个a和一个b要你求a%b的结果

  • 输入

    多组输入 (最多1e5组)
    对于每一组输入两个整数a和b(-1e9<=a<=1e9,1<=b<=1e9)

    输出

    输出a%b
    结果为非负数

    样例输入 复制

    -1 2
    2 3

    样例输出 复制

1
2

分析时发现不就是取余嘛,很简单啊,看到输入样例时很懵逼,怎么会有负数呢,这个%其实在这个题中时取模符号modc语言中没有取模这个符号但可以使用相应公式对其转化而得到取模的结果,大家对公式推导有兴趣的可以了解,我就不推导了。 

#include 
#include 
#include 
#include //a%b(??)
int main() {
	long long x,y;
	while (~scanf("%lld %lld", &x, &y))
	{
		printf("%lld\n", (x % y + y) % y);
	}
}

10.最大和最小

题目描述

给定两个整数 n 和 m,要求 m个整数的和为n,m个整数的乘积最大。
满足条件的整数序列可能有多种,请你输出一个字典序最小的满足条件的序列。

输入

第一行输入两个整数 n和m (1 <= n <= 1e9), (1 <= m <= n <= 1e6)。

输出

输出m个用空格隔开的整数表示字典序最小的一种方案数。

样例输入 复制

7 3

样例输出 复制

2 2 3

这题分析后其实就是个数学题,高中学的不等式可以证明得到当俩个数最接近的时候乘积最大,故这一题要满足分解后的数字要最接近平均值,所以我们可以把平均值求出来,接着把多出来的数依次分给数组中的元素,这个有点不好表达,直接看代码

#include 
#include 
#include 
#include 
int cmp1(const void *p1,const void *p2)
{
	return(*(int*)p1-*(int*)p2);
}
long long num[1000005]={0};
int main()
{
	long long a,b;
	scanf("%lld %lld",&a,&b);
	int temp=a/b;//平均值
	for(int i=0;i

11.小学生分数计算

分数的计算想必各位学弟学妹都会吧,现在要求你写一个程序来实现小学分数的加减法计算。给出2个分数,求他们的结果。

输入

输入包含多行数据 
每行数据是一个字符串,格式是"a/boc/d"。 
其中a, b, c, d是一个0-9的整数。o是运算符"+"或者"-"。 
数据以EOF结束 
输入数据保证合法

输出

对于输入数据的每一行输出两个分数的运算结果。 
注意结果应符合书写习惯,没有多余的符号、分子、分母,并且化简至最简分数

样例输入 复制

1/8+3/8
1/4-1/2
1/3-1/3

样例输出 复制

1/2
-1/4
0

 看起来好像很简单,其实也很简单,只不过要注意细节看代码看代码

#include 
#include 
#include 
#include 
int MAX(int a,int b)//求大的函数
{
	return a>b?b:a;
}
int gys(int a,int b)//最小公约数函数
{
	int	n=MAX(a,b);int data;
	for(int i=1;i<=n;i++)
	{
		if(a%i==0&&b%i==0)
		{
			data=i;
		}
	}
	return data;
}
int min(int a,int b)//求小的函数
{
	return a>b?b:a;
}
int main()
{
	int a,b,c,d;char ch;
	while(~scanf("%d/%d%c%d/%d",&a,&b,&ch,&c,&d))//分别输入分子分母,分子分母
	{
		int z,m,k;
		//加减分别考虑
		if(ch=='+')
		{
			z=a*d+c*b;
			m=b*d;
			if(z%m==0)printf("%d\n",z/m);//如果可以整除那么就直接输出除后的整数
			//不能整除时
			else 
			{
				k=gys(z,m);//求出最大公约数
				z/=k;//分子分母除以最大公约数
				m/=k;
				printf("%d/%d\n",z,m);
			}
		}
		//减法情况同上
		if(ch=='-')
		{
			z=a*d-c*b;
			m=b*d;
			if(z%m==0)printf("%d\n",z/m);
			else 
			{
				int temp1=z,temp2=m;
				k=gys(abs(temp1),abs(temp2));
				z/=k;
				m/=k;
				printf("%d/%d\n",z,m);
			}
		}
	}

}

12.做串串题咯

题目描述

wcp学长非常喜欢字符串,于是乎他也想考考你是不是也学了串串,现在他给定你两个字符串s和t,如果t是s的子串(s包含t)则输出Yes,否则输出No

输入

两个字符串s和t

输出

Yes或No

样例输入 复制

sss
s

样例输出 复制

Yes

提示

字符串s和t的长度不超过1000

该代码是打比赛的时候打的,写的比较急,会有一点小瑕疵,大家多多指点。

#include 
#include 
#include 
#include 
int main()
{
	char ch[1001],sh[1001];
	int flag[1000]={0},flag1[1000]={0},temp;
	scanf("%s",ch);//输入字符串1
	getchar();
	scanf("%s",sh);//输入字符串2
	int len1=strlen(ch);//求出其长度
	int len2=strlen(sh),cnt=0;
	temp=len2;
	for(int i=0;i=flag1[i])cnt+=flag1[i];//这句if语句很关键
		//如果对应的桶里面存在字符,且桶一大于桶二的数量则cnt数量变化
	}
	if(cnt==temp)printf("Yes");//如果cnt的数量和输入的字符串2长度一样,说明2为1的子字符串
	else printf("No");
}

你可能感兴趣的:(c语言)