很久一起折腾过这道题。印象中折腾了很久,但是一直弄不出来。现在有了经验,顺利做出来了,感觉非常棒,自己终于有了提升。
Search Problems,用Dfs解。由于没有考虑数字排序的问题错了几次。
//ZOJ 1204Additive equations
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <algorithm>
//#define DEBUG
using namespace std;
int NumSum, Num[35], Equ[15000][35], EquLen[15000], MaxNum;
int EquPtr, EquTmp[35], EquTmpPtr, NumPtr;
bool isFind, isOutput[15000];
void Dfs(void)
{
if (NumPtr >= NumSum - 1)
return;
int add;
for (int i = NumPtr; i < NumSum; i ++)
{
EquTmp[EquTmpPtr] = Num[i];
EquTmpPtr ++;
add = 0;
for (int j = 0; j < EquTmpPtr; j ++)
{
add += EquTmp[j];
}
if (add <= MaxNum)
{
#ifdef DEBUG
if (EquTmp[0] == 1 && EquTmp[1] == 4)
cout << "here" << endl;
#endif
for (int j = i + 1; j < NumSum; j ++)
{
if (i != j && add == Num[j])
{
isFind = true;
for (int k = 0; k < EquTmpPtr; k ++)
{
Equ[EquPtr][k] = EquTmp[k];
}
Equ[EquPtr][EquTmpPtr] = add;
EquLen[EquPtr] = EquTmpPtr + 1;
EquPtr ++;
break;
}
}
NumPtr = i + 1;
Dfs();
}
EquTmp[EquTmpPtr] = 0;
EquTmpPtr --;
}
return;
}
void Output(void)
{
#ifdef DEBUG
cout << EquPtr << endl;
#endif
int min_len, out_cnt = EquPtr;
memset(isOutput, 0x0, sizeof(isOutput));
while (out_cnt > 0)
{
min_len = 35;
for (int i = 0; i < EquPtr; i ++)
{
if (isOutput[i] == false && EquLen[i] < min_len)
min_len = EquLen[i];
}
for (int i = 0; i < EquPtr; i ++)
{
if (isOutput[i] == false && EquLen[i] == min_len)
{
isOutput[i] = true;
out_cnt --;
for (int j = 0; j < EquLen[i] - 2; j ++)
{
cout << Equ[i][j] << "+";
}
cout << Equ[i][EquLen[i] - 2] << "="
<< Equ[i][EquLen[i] - 1] << endl;
}
}
}
}
int main(int argc, char *argv[])
{
int case_sum;
cin >> case_sum;
while (case_sum --)
{
cin >> NumSum;
MaxNum = 0;
for (int i = 0; i < NumSum; i ++)
{
cin >> Num[i];
if (Num[i] > MaxNum)
MaxNum = Num[i];
}
sort(&Num[0], &Num[NumSum - 1] + 1);
EquPtr = 0;
EquTmpPtr = 0;
memset(EquTmp, 0x0, sizeof(EquTmp));
NumPtr = 0;
isFind = false;
Dfs();
Output();
if (isFind == false)
{
cout << "Can't find any equations." << endl;
}
cout << endl;
}
return 0;
}