#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
using namespace std;
long long r;
string s;
int vis[300];
char ss[100];
map<char, int>mm;
string maxn;
void init()
{
int c = 'A';
for (int i = 1; i <= 26; i++)
{
mm[c++] = i;
}
}
void mz()
{
//现在回过头去看这个 其实这几行也挺蠢的
int z = ss[4];
int y = ss[3];
int x = ss[2];
int w = ss[1];
int v = ss[0];
long long sum = v - w * w + x * x * x - y * y * y * y + z * z * z * z * z;
if (sum==r)
{
string t;
stringstream a;
//此处强制转换失败 才出此下策 不知各位高人有何其他妙招
char q[6];
for (int i = 0; i < 5; i++)
q[i] = ss[i] + 'A'-1;
q[5] = '\0';
//我已经不想再用strcmp了 真的忘了大小正负 还有相同是0这回事
a << q;
t = a.str();
if (maxn < t)
maxn = t;
}
}
void dfs(int n)
{
if (n==5)
{
mz();
return;
}
for (int i = 0; i < s.length(); i++)
{
//标记还是得有的 原来想用stack做 但是发现没法查看是否存在过相同的字母 后来用vector 用find 结果太慢
//我觉得这两种可能真的可行但是我……QAQ
//仔细想了下 可能还是不行的 因为没法完全回溯到上一状态 存疑 以后再研究
//另外就是 我这边本来用string的 但是 string为空的情况下无法直接用[]调用 所以……
//现在想了下 其实可以先maxn和ss全赋值0然后比较是否全为0确认是否有解决方案
if (vis[mm[s[i]]]==0)
{
ss[n] = mm[s[i]];
vis[mm[s[i]]] = 1;
dfs(n+1);
vis[mm[s[i]]] = 0;
}
}
}
int main()
{
while (cin >> r >> s && r != 0 && s != "END")
{
init();
memset(vis, 0, sizeof(vis));
memset(ss, 0, sizeof(ss));
maxn.clear();
sort(s.begin(), s.end());//这一行……真的毫无影响……可能可以加速?
dfs(0);
if (maxn.length() == 0)
puts("no solution");
else
cout << maxn << endl;
}
system("pause");
return 0;
}
我以为深搜掌握的差不多了 然鹅 现实给了一记响亮的耳光……看起来蛮简单的但是我花了很多时间 因为回溯的问题就很烦
第一遍的思路是 stack+string 但是没有标记 然后整个过程就很繁琐
第二遍的思路是 vector+string 没有标记 而且最致命的就是覆盖的问题 所以前四个字母只会是ABCD so……
然后翻博客去了
就很简单的一个深搜题 然后把覆盖的也解决了就很简单的AC了
搞什么嘛弄了那么久……
这个题目其实暴力循环也可以过 但是 这样就很没趣(除非比赛……)