第三次上机总结

第三次上机总结

问题

  • 已学内容的熟练度有待加强
  • 对于for循环不太熟练
  • switch使用方法(见下) break的位置不对.有异常的退出循环的情况.在循环中要注意switch的使用
    int op;//如果是char就直接写case'A': case 'b': 等
    switch(op){
    case 1:
        break;
    case 2:
        break;
    case '1':
        //相当于case 49 因为49=='1'
        break;
    default:
        break;
    }

AC代码

A 倒三角

  • 杜晨鸿没工资辣
  • 找规律 2层循环解决
  • 问题:想复杂了 不会写循环 或者换行的位置不对
#include <stdio.h>
int main(){
	int n,i,j;
	scanf("%d",&n);
	for(i = 0;i < n;i++){
		for(j = 0;j < 2 * n - 1 - i;j++){
			if(j<i){
                putchar(' ');
            }else{
                putchar('$');
            }
		}
		putchar('\n');
	}
	return 0;
}

B 荷荷学妹赚基金

  • if-else判断 注意数据范围.
  • 后面有浮点数操作 所以建议直接读浮点数 注意scanf在此处的使用
  • 可以不开数组
#include <stdio.h>
int main(){
    double cur;
	int n;
	scanf("%d",&n);
	while(n--){
		scanf("%lf",&cur);
		if(cur <= 800.){
			printf("%.2f\n",cur);
		}
		else if(cur <= 1500.){
			printf("%.2f\n",cur - (cur - 800) * 0.2);
		}
		else{
			printf("%.2f\n",cur - (cur - 1500) * 0.25 - 700 * 0.2);
		}
	}
    return 0;
}

C 一天不用switch我浑身难受

  • 题目背景似乎是造随机数
  • 只要细致就能拿分 if-elseswitch
#include<stdio.h>
unsigned seed;
long long a, b;
long long ans = 0;
int n, i;
int op;
int scheme[35];
int main() {
    scanf("%d%u", &n, &seed);
    for (i = 0; i <= 31; ++i) scanf("%d", &scheme[i]);
    while(n--) 
	{
		seed ^= seed << 13;
		seed ^= seed >> 17;
		seed ^= seed << 5;
		op = scheme[seed & 31] & 31;
		a = n ^ 1145141919810ll;
		b = n ^ 1919810114514ll;
		switch(op)
		{
			case 0: ans += a + b;break;
			case 1: ans += a - b;break;
			case 2: ans += a * b;break;
			case 3: ans += a / b;break;
			case 4: ans += a % b;break;
			case 5: ans += a & b;break;
			case 6: ans += a | b;break;
			case 7: ans += a ^ b;break;
			case 8: ans -= a ^ b;break;
			case 9: ans -= a | b;break;
			case 10: ans -= a & b;break;
			case 11: ans -= a % b;break;
			case 12: ans -= a / b;break;
			case 13: ans -= a * b;break;
			case 14: ans -= a - b;break;
			case 15: ans -= a + b;break;
			case 16: ans &= a * b;break;
			case 17: ans &= a / b;break;
			case 18: ans &= a + b;break;
			case 19: ans &= a - b;break;
			case 20: ans &= a | b;break;
			case 21: ans &= a ^ b;break;
			case 22: ans &= a % b;break;
			case 23: ans &= a & b;break;
			case 24: ans ^= a / b;break;
			case 25: ans ^= a * b;break;
			case 26: ans ^= a - b;break;
			case 27: ans ^= a + b;break;
			case 28: ans ^= a ^ b;break;
			case 29: ans ^= a | b;break;
			case 30: ans ^= a & b;break;
			case 31: ans ^= a % b;break;
		} 
    }
    printf("%lld", ans);
    return 0;
}  

D 年 度 好 题

  • 分数的计算(数学问题)
  • 一行代码解决最大公约数求法
int gcd(int m,int n){
    return m%n?gcd(n,m%n):n;
}
  • 希望同学们善于利用以前的代码(非递归版本)
#include <stdio.h>
int gcd(int m,int n){
	return m % n?gcd(n,m % n):n;
}
int main(){
	int a,b,c,d,p,q,g;
	scanf("%d/%d %d/%d",&a,&b,&c,&d);
	q = b * d;
	p = a * d + b * c;
	g = gcd(p,q);
	printf("%d/%d\n",p / g,q / g);
	return 0;
}

E 银行

  • 浮点数计算问题,前面的误差会被指数函数放大
  • 题目作者的意思是 比较两个利率然后算指数
#include <stdio.h>
#include <math.h>
int eq(double a,double b){//这个函数用于判断浮点数相等
	return fabs(a - b) < 1e-8;
}
int main(){
	double s,m,n,s1,s2;int t;
	scanf("%lf%lf%lf%d",&s,&m,&n,&t);
	double p1,p2;
	p1=pow((1.00 + m / 100.0),t);
	p2=pow(pow(1.00 + n / 100.00,4.0),t);
	s1 = s * p1;s2 = s * p2;
	//printf("%.2f\n%.2f\n",s1,s2);
	if(eq(p1,p2)){
		printf("%.2f\n%.2f\n",s1,s1);
		puts("Whatever");
	}
	else if(p1 > p2){
		printf("%.2f\n%.2f\n",s1,s2);
		puts("51Mole!!");
	}
	else{
		printf("%.2f\n%.2f\n",s1,s2);
		puts("51Seer!!");
	}

	return 0;
}

F 五荷一点都不喜欢重复

  • 全排列问题 循环当然可以做 就是麻烦
  • 官方题解大概长这样
#include<stdio.h>

int main()
{
	int m,n,single,ten,hund,thou,tk;
	scanf("%d%d",&m,&n);
	if(n==3)
	{
		for(hund=1;hund<=m;hund++)
			for(ten=1;ten<=m;ten++)
				for(single=1;single<=m;single++)
					if(hund!=ten&&ten!=single&&hund!=single)
						printf("%d%d%d\n",hund,ten,single);
	}
	else if(n==4)
	{
		for(thou=1;thou<=m;thou++)
			for(hund=1;hund<=m;hund++)
				for(ten=1;ten<=m;ten++)
					for(single=1;single<=m;single++)
						if(hund!=ten&&ten!=single&&hund!=single&&thou!=hund&&thou!=ten&&thou!=single)
							printf("%d%d%d%d\n",thou,hund,ten,single);
	}
	else if(n==5)
	{
		for(tk=1;tk<=m;tk++)
			for(thou=1;thou<=m;thou++)
				for(hund=1;hund<=m;hund++)
					for(ten=1;ten<=m;ten++)
						for(single=1;single<=m;single++)
							if(hund!=ten&&ten!=single&&hund!=single&&thou!=hund&&thou!=ten&&thou!=single&&tk!=thou&&tk!=hund&&tk!=ten&&tk!=single)
								printf("%d%d%d%d%d\n",tk,thou,hund,ten,single);
	}
	return 0;
}
  • 另外一种简单而优雅(?)的方法是 递 归
#include <stdio.h>
int vis[12] = {0},res[12] = {0},m,n;
void dfs(int k){
	int i;
	if(k == n){
		for(i = 0;i < n;i++){
			putchar(res[i]+'0');
		}
		putchar('\n');
		return;
	}
	else{
		for(i = 1;i <= m;i++){
			if(!vis[i]){
				vis[i] = 1;
				res[k] = i;
				dfs(k + 1);
				vis[i] = 0;
			}
		}
	}
}
int main(){
	scanf("%d%d",&m,&n);
	dfs(0);
	return 0;
}

G 缺项一元三次方程

  • 数学问题,而且公式给了 需要掌握math.h的函数用法
  • 在C89中,使用double pow(double base,double exponent)计算开立方。但是,它要求base不能是负数。对于负数的base
  • 处理方法当然是 化 正
  • 助教说不推荐下面用'qsort'的写法 三个数排序还是很好写的:)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int cmp(const void *p,const void *q){
	double a = *((double *)p),b = *((double *)q);
	return a == b?0:(a > b?1:-1);
}
int main(){
	double p,q,x[4] = {0};
	scanf("%lf%lf",&p,&q);
	double q2 = q * q,p3 = p * p * p;
	double PI = acos(-1.0);
	if(q2 > p3){
		double tmp = q - sqrt(q2 - p3);
		double tmp2 = q + sqrt(q2 - p3);
		printf("%.10f",(tmp2 > 0?pow(tmp2,1 / 3.0):(-1) * pow(-tmp2,1 / 3.0)) + (tmp > 0?pow(tmp,1 / 3.0):(-1) * pow(-tmp,1 / 3.0)));

	}
	else{
		x[0] = 2 * sqrt(p) * cos(acos(q / sqrt(p3)) / 3.);
		x[1] = 2 * sqrt(p) * cos(acos(q / sqrt(p3)) / 3. + 2 * PI / 3.);
		x[2] = 2 * sqrt(p) * cos(acos(q / sqrt(p3)) / 3. + 4 * PI / 3.);
		qsort(x,3,sizeof(double),cmp);
		printf("%.10f %.10f %.10f",x[0],x[1],x[2]);
	}
	return 0;
}

H 朵朵的日期计算

  • 日期计算(这是曹助教感觉很头痛的事情)建议存模板
  • Zeller公式 闰年
  • 打包成函数真舒服
#include <stdio.h>
#include <math.h>
int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int zeller(int y,int m,int d){
	int c = y / 100;y = y % 100;
	int r= (y + (y / 4) + (c / 4) - 2 * c + (13 * (m + 1) / 5) + d - 1) % 7;
	return r < 0?r + 7:r;
}
int leapyear(int y){
	return((y % 400 == 0) || ((y % 100 != 0) && (y % 4 == 0)));
}
int dayofyear(int y,int m,int d){
	days[2] = leapyear(y)?29:28;
	int s = 0,i;
	for(i = 1;i < m;i++){
		s += days[i];
	}
	s += d;
	return s;
}
int main(int argc,char **argv){

	int y1,y,m,d;
	scanf("%d%d%d%d",&y1,&y,&m,&d);
	int w51 = zeller(y1,5,1);
	int t = w51?15 - w51:8;
	int dt1 = dayofyear(y1,m,d),dt2 = dayofyear(y1,5,t);
	printf("%d\n",t);
	printf("%d\n",abs(dt1-dt2));
	return 0;
}
posted @ 2021-03-25 23:30  仪光19暴毙开发者  阅读(27)  评论(0编辑  收藏  举报