痛恨,当时这道题没有做出来,没有安下心认真分析。当时作出了第二道题,迷宫问题,因为以前见过类似的(具体缺乏锻炼,调试了老半天)。
题目如下:
-----------------------------------
Description
Input
Output
Sample Input
5 5 1 5
Sample Output
5*(5-(1/5))
---------------------------------------
认真分析,不改变位置顺序,当时被这个搞死了。但是后来发现这是个很好的限制条件,其实是简单了,而不是复杂了。
分析如下:
1)五种操作顺序
给定4个正整数,a b c d .他们的操作顺序共有六种A(3,1)
//1((a b) c) d
//2(a b) (c d)
//3(a (b c)) d
//4a ((b c) d)
//5a (b (c d))
//*6**(a b) (c d) 第六种和第二种其实同样的,不管是先算前两个 还是先算后两个 结果是一样的。
2)每个操作中都含有4中操作运算(+、-、*、/)
根据这个思想写的伪代码:
每中操作类型 根据 所操作的间隔顺序不同,传递进不同的参数
//1((a b) c) d if( findMatch(1,2,3)) //2(a b) (c d) if( findMatch(1,3,2)) //3(a (b c)) d if(findMatch(2,1,3)) //4a ((b c) d) if(findMatch(2,3,1)) //5a (b (c d)) if(findMatch(3,2,1))
int findMatch(int inter1,int inter2,int inter3) { do{ tempSum=MathChoice(number[interBefore(inter1)],number[interAfter(inter1)]) if(inter2>inter1) tempSum=MathChoice(tempSum,number[interAfter(inter2)]); else if(inter2<inter1) tempSum=MathChoice(number[interBefore(inter2)],tempSum); if(inter3>inter2) tempSum=MathChoice(tempSum,number[interAfter(inter3)]) else if(inter3<inter2) tempSum=MathChoice(number[interBefore(inter3)],tempSum); if(tempSum==24) //find the answer { return 1; } }while(); }
可以将MathChoice抽象出来,它包含4中操作运算。
#define MathChoice(i, a, b) / do { / if(i==0) / add(a,b); / else if(i==1) / minus(a,b); / else if(i==2) / mutiply(a,b); / else if(i==3) / divide(a,b); / }while(0);
根据i值不同调用不同的函数。(这里宏定义也遇到过问题,原来把操作的值返回如return add(a,b); 因为宏定义不能返回值,
所以改了,设了一个全局变量 static float tempSum=0;来记录各个操作后的结果)
间隔的顺序是1,2,3
#define interBefore(a) a-1 //当前间隔的前一个数
#define interAfter(a) a //当前间隔后一个数
3)输出 封装
因为各个操作类型都定义好了,而每个操作类型的()的位置是可以定的,变的只是操作符的类型.
因此需要记录每个间隔的操作符类型。在得到正确结果的时候将当前的操作符记录下来。+ - * / if(inter1==1) //存放间隔 的操作符,间隔位置可能不同,但是operations按第 1,2,3间隔顺序存放 operations[0]=i; else if(inter2==1) operations[1]=i; else if(inter3==1) operations[2]=i; if(inter1==2) operations[0]=j; else if(inter2==2) operations[1]=j; else if(inter3==2) operations[2]=j; if(inter1==3) operations[0]=k; else if(inter2==3) operations[1]=k; else operations[2]=k;
以下是具体的源代码:
#include <stdio.h> #include <stdlib.h> #include <math.h> float number[4]; static float tempSum=0; #define interBefore(a) a-1 #define interAfter(a) a int operations[3]; //stored 3 interOpertions between them void add(float a,float b) { tempSum=a+b; } void minus(float a,float b) { tempSum=a-b; } void mutiply(float a, float b) { tempSum= a*b; } void divide(float a,float b) { tempSum= a/b; } #define MathChoice(i, a, b) / do { / if(i==0) / add(a,b); / else if(i==1) / minus(a,b); / else if(i==2) / mutiply(a,b); / else if(i==3) / divide(a,b); / }while(0); int findMatch(int inter1,int inter2,int inter3) { tempSum=0; /* pseduo code beolow: do{ tempSum=MathChoice(number[interBefore(inter1)],number[interAfter(inter1)]) if(inter2>inter1) tempSum=MathChoice(tempSum,number[interAfter(inter2)]); else if(inter2<inter1) tempSum=MathChoice(number[interBefore(inter2)],tempSum); if(inter3>inter2) tempSum=MathChoice(tempSum,number[interAfter(inter3)]) else if(inter3<inter2) tempSum=MathChoice(number[interBefore(inter3)],tempSum); if(tempSum==24) //find the answer { return 1; } }while(); */ //have each operation kind here for(int i=0;i<4;i++) for(int j=0;j<4;j++) for(int k=0;k<4;k++) { MathChoice(i,number[interBefore(inter1)],number[interAfter(inter1)]); if(inter2>inter1) MathChoice(j,tempSum,number[interAfter(inter2)]); // else if(inter2<inter1) MathChoice(j,number[interBefore(inter2)],tempSum); if(inter3>inter2) MathChoice(k,tempSum,number[interAfter(inter3)]) else if(inter3<inter2) MathChoice(k,number[interBefore(inter3)],tempSum); if(tempSum==24) //find the answer { if(inter1==1) //存放间隔 的操作符,间隔位置可能不同,但是operations按第 1,2,3间隔顺序存放 operations[0]=i; else if(inter2==1) operations[1]=i; else if(inter3==1) operations[2]=i; if(inter1==2) operations[0]=j; else if(inter2==2) operations[1]=j; else if(inter3==2) operations[2]=j; if(inter1==3) operations[0]=k; else if(inter2==3) operations[1]=k; else operations[2]=k; return 1; } } return 0; } void outputOperations(int kind) { switch(kind) { case 0: printf("+"); break; case 1: printf("-"); break; case 2: printf("*"); break; case 3: printf("/"); break; } } int match() { //just 6 kinds, but real is just 5 kinds //1((a b) c) d if( findMatch(1,2,3)) // 1 means a and b, 2 means that then with { printf("((%d",(int)number[0]); outputOperations(operations[0]); printf("%d)",(int)number[1]); outputOperations(operations[1]); printf("%d)",(int)number[2]); outputOperations(operations[2]); printf("%d",(int)number[3]); return 1; } //2(a b) (c d) if( findMatch(1,3,2)) { printf("(%d",(int)number[0]); outputOperations(operations[0]); printf("%d)",(int)number[1]); outputOperations(operations[1]); printf("(%d",(int)number[2]); outputOperations(operations[2]); printf("%d)",(int)number[3]); return 1; } //3(a (b c)) d if(findMatch(2,1,3)) { printf("(%d",(int)number[0]); outputOperations(operations[0]); printf("(%d",(int)number[1]); outputOperations(operations[1]); printf("%d))",(int)number[2]); outputOperations(operations[2]); printf("%d",(int)number[3]); return 1; } //4a ((b c) d) if(findMatch(2,3,1)) { printf("%d",(int)number[0]); outputOperations(operations[0]); printf("((%d",(int)number[1]); outputOperations(operations[1]); printf("%d)",(int)number[2]); outputOperations(operations[2]); printf("%d)",(int)number[3]); return 1; } //5a (b (c d)) if(findMatch(3,2,1)) { printf("%d",(int)number[0]); outputOperations(operations[0]); printf("(%d",(int)number[1]); outputOperations(operations[1]); printf("(%d",(int)number[2]); outputOperations(operations[2]); printf("%d))",(int)number[3]); return 1; } //*6**(a b) (c d) is the same as before as the 2 return 0; } int main() { for(int i=0;i<4;i++) { scanf("%f",&number[i]); } match(); return 0; }
删除了伪代码注释 ,排名又往前靠了,看来代码的大小也很影响ranklist的。也就是如果有些变量名可以短的话尽量短。