CCF模拟试题 201903-2 二十四点(C语言版,100')

代码

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

/*
通过递归函数实现24点游戏

对算术式 a ? b ? c ? d  从左到右顺序计算,

因为 +,-优先级相同, x, /优先级相同; 但x,/优先级高于加减优先级
所以当第1个 ? 为 +,-时先按最低优先级处理,即先不计算 a ? b。
	此时,将 b 作为 第2个 ? 的左操作数, c 作为 第2个 ? 的右操作数 计算 b ? c, 当 得到 b ? c的计算结果 Rbc 后 再将 Rbc 作为 第1个 ? 的右做操作数计算 a ? Rbc 

 	但是,当第1个 ? 为 x,/时按最高优先级处理,即先计算 a ? b = Rab,
	 	此时,将 计算结果 Rab 作为 第2个 ? 的做操作数, c作为 第2个 ? 的右操作数 计算 Rab ? c 
	 	
	类似的,在计算 b ? c 或 Rab ? c时,如果第2个? 为 +,- 时,先将本次(即第2个) ? 的右操作数 做为 下一次(即第3个) ? 的左操作数去计算下一次的 ?运算
		如果第2个 ? 为 x,/时, 先计算本次 ?运算,再将本次运算结果作为下一次 ?的左操作数去进行下一次 ? 运算 
	...
	
	直到最后一个 ? 时,直接进行计算,再把计算结果返回至上一个 ? , 作为上一个 ? 的右操作数,最终完成所有 ? 的运算。 
	
	需要注意的是 如果当前 ? 运算为 - 时,要把当前 ? 的右操作数的相反数作为下一次 ? 运算的 左操作数 ,并且把当前为 - 运算(即减运算)的 ? 改成 + 运算(即加运算) 
 

*/ 

struct Item{
	int nums[4];
	char signs[3];
};

int main() {
	void calc(struct Item *p, int n);
	int func(char sign, int num1, int num2, struct Item *p, int count);
	struct Item *p;
	int n,i,j;
	char str[8];

	scanf("%d",&n);
	
	p = (struct Item *)malloc(n * sizeof(struct Item));

	for(i=0; i<n; i++){
		//要求输出的是字符串 
//		scanf("%s", str);
//		for(j=0; j<=3; j++) {
//
//			*((p+i)->nums + j) = str[2*j] - 48;
//
//			if(j != 3) {
//				*((p+i)->signs + j) = str[2*j+1];
//			}
//		}
		//按如下格式输入也可以 
		scanf("%d%c%d%c%d%c%d",(p+i)->nums, (p+i)->signs,(p+i)->nums+1, (p+i)->signs+1,(p+i)->nums+2, (p+i)->signs+2,(p+i)->nums+3);
	}


	calc(p, n);	 

	free(p);

	return 0;
}



void calc(struct Item *p, int n) {
	int func(char sign, int num1, int num2, struct Item *p, int count);
	int result;
	int i;
	int count,num1,num2;
	char sign;

	for(i=0; i<n; i++) {
		count = 1;
		num1 = *((p+i)->nums);
		num2 = *((p+i)->nums+1);
		sign = *((p+i)->signs);
		result = func(sign, num1, num2, p+i, count);
//		printf("result: %d", result);
		if (result == 24) {
			printf("Yes\n");
		}else {
			printf("No\n");
		}
	}
		
}

int func(char sign, int num1, int num2, struct Item *p, int count) {
//	printf("num1=%d, num2=%d, count=%d, sign=%c\n", num1, num2, count, sign); 
	int result;
	int tmp;
	if (count != 3) {

		//取item.signs数组中的元素时,已传入的形参count为索引
		//取item.nums数组中的元素时,需要已 count+1 为索引
		
		//不能在形参sign的位置上已 count++ 的方式,在给形参sign赋以count原值后,妄想以形参count加1后的值 赋值给形参 num2 和 count
		//因为按照这个方式,func函数中递归调用的func函数形参 num2 和 count 还是 未加 1 之前的count值 
		
		//以下注释为错误示例: 
//		switch(sign) {
//			case '+':
//				result = num1 + func(*(p->signs+(count++)), num2, *(p->nums+count), p, count);
//			break;
//			case '-':
//				result = num1 + func(*(p->signs+(count++)), -num2, *(p->nums+count), p, count);
//			break;
//			case 'x':
//				result = func(*(p->signs+(count++)), num1 * num2, *(p->nums+count), p, count);
//			break;
//			case '/':
//				result = func(*(p->signs+(count++)), num1 / num2, *(p->nums+count), p, count);
//			break;
//		}

		tmp = count;
		++count;
		switch(sign) {
			case '+':
				result = num1 + func(*(p->signs+tmp), num2, *(p->nums+count), p, count);
			break;
			case '-':
				result = num1 + func(*(p->signs+tmp), -num2, *(p->nums+count), p, count);
			break;
			case 'x':
				result = func(*(p->signs+tmp), num1 * num2, *(p->nums+count), p, count);
			break;
			case '/':
				result = func(*(p->signs+tmp), num1 / num2, *(p->nums+count), p, count);
			break;
		}
	}else {
		
		switch(sign) {
			case '+':
				result = num1 + num2;
			break;
			case '-':
				result = num1 - num2;
			break;
			case 'x':
				result = num1 * num2;
			break;
			case '/':
				result = num1 / num2;
			break;
		}
	}
	
	return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值