HDU 1015(dfs+回溯(?))

#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了

搞什么嘛弄了那么久……

这个题目其实暴力循环也可以过 但是 这样就很没趣(除非比赛……)

猜你喜欢

转载自blog.csdn.net/qq_42191950/article/details/82946162