1 /*****************************************************************************
2 *输入一个正整数X,在下面的等式左边的数字之间添加 + 号或者 - 号,使得等式成立。
3 *1 2 3 4 5 6 7 8 9 = X
4 *比如:
5 *12 - 34 + 5 - 67 + 89 = 5
6 *1 + 23 + 4 - 5 + 6 - 7 - 8 - 9 = 5
7 *请编写程序,统计满足输入整数的所有整数个数。
8 *输入: 正整数,等式右边的数字
9 *输出: 使该等式成立的个数
10 *样例输入:5
11 *样例输出:21
12 *************************************************************************/
13
14 //使用链表是因为计算等式的值的时候,容易将10*的好处理,把节点直接删掉,但是要管理内存,
15 //复制链表的时候也不像数组那样方便,总之是很麻烦,权单熟悉一下链表的插入删除操作吧~~
16 //用数组模拟链表要方便多了,1 2 3 + 4 5,把数据从数组里读出来,另外设个a[9]-{0},用来存储
17 //得到的值,简单多了。
18 #include <iostream>
19 #include<ctime>
20 #include<string>
21 using namespace std;
22 const int target=5;//等式右边的值
23 const n=9;//等式左边有几个不同的数?比如1~4是5个,1~9是9个
24 struct node{
25 int data;
26 char operate;
27 node *next;
28 };
29 void copyChain(node *&header,node *&opp)//拷贝链表,这个好麻烦,用数组模拟链表简单一些
30 {
31 opp=NULL;
32 node *q=header;
33 node *t=opp;
34 while(q)
35 {
36 node *p=new node;
37 p->data=q->data;
38 p->operate=q->operate;
39 p->next=NULL;
40 if(opp==NULL)
41 opp=p;
42 else
43 t->next=p;
44 t=p;
45 q=q->next;
46 }
47 }
48
49 int answer(node *&t)//计算等式左边的值
50 {
51 int k1=0,k2=0;
52 node *q=t;//操作链表的时候,先拷贝个头指针,用于指向操作的位置
53 while(q!=NULL && q->next!=NULL)//这里要弄明白
54 {
55 if(q->operate==' ')//先把乘10的部分计算出来,合并,删除节点
56 {
57 node *p=q->next;
58 q->data=10*q->data+p->data;
59 q->operate=p->operate;
60 q->next=p->next;
61 delete p;
62 }
63 else q=q->next;//这个不能丢,死循环了
64 }
65 if(t->next==NULL)//若删除的就剩一个节点了,接着返回
66 return t->data;
67 q=t;
68 k2=q->data;
69 while(q->next!=NULL)//计算加减法
70 {
71 if(q->operate=='+')
72 k1=q->next->data;
73 else if(q->operate=='-')
74 k1=-q->next->data;
75 q=q->next;
76 k2+=k1;
77 }
78 return k2;
79 }
80
81 char transfer(const int i)//对应符号转换
82 {
83 if(i==0)
84 return ' ';
85 if(i==1)
86 return '+';
87 if(i==2)
88 return '-';
89 return ' ';
90 }
91
92 void dfs(node *&opp,node *&temp,int &count)//指针引用,其实是想拷贝一个链表传递过来,不知道怎么实现
93 //temp是递归的时候用于记录操作的位置,opp是目前整个链表的情况
94 {
95 if(temp->next==NULL)
96 {
97 node *t=opp;
98 copyChain(opp,t);//复制链表,这个必须复制
99 int mm=answer(t);//计算值
100 node *p=t;
101 while(t)//把复制的链表内存释放了
102 {
103 p=t->next;
104 delete t;
105 t=p;
106 }
107
108 if(mm==target)//比较
109 {
110 count++;
111 p=opp;//操作链表前复制头结点
112 while(p)
113 {
114 cout<<p->data<<p->operate;
115 p=p->next;
116 }
117 cout<<"="<<target<<endl;
118 }
119 return;
120 }
121 int i;
122 for(i=0;i<3;i++)
123 {
124 temp->operate=transfer(i);//可以简化程序 char ch={' ','+','-'};...=ch[i];
125 dfs(opp,temp->next,count);//深度优先搜索
126 }
127 }
128
129 int main()
130 {
131 int i,count=0;
132 node *header,*opp;
133 header=NULL;
134 opp=header;
135 for(i=1;i<=n;i++)
136 {
137 node *q=new node;
138 q->data=i;
139 q->operate=' ';
140 q->next=NULL;
141 if(header==NULL)
142 header=q;
143 else
144 opp->next=q;
145 opp=q;
146 }
147 dfs(header,header,count);//传递指针的引用
148 cout<<count<<endl;
149 node *p;
150 while(header)
151 {
152 p=header->next;
153 delete header;
154 header=p;
155 }
156 return 0;
157
158 }
结果:
深度优先遍历,9个数有8个符号,在这8个符号位上各有3种可能,遍历检查
感觉整的有点复杂了,拿数组代替链表,程序会简单很多,不知道有没有别的巧妙的思路来解决这个问题~