这道题是用DFS做的,尝试了所以的可能性,然后取最短的。看标准答案能够通过总结规律直接输出出来,效率明显高很多,但是由于测试数据特别小,这道题用这种穷举的方法都很快过了。
每次都尝试四种可能性,白跳黑,移白,移黑,黑跳白。唯一的难点在于记录已尝试过的方法。刚开始用的set,结果出现“
terminate_called_after_throwing_an_instance_of_'std::bad_alloc' __what():__std::bad_alloc”错误。然后就改成了trie。trie可以节省solution重复的部分,因而需要的空间小,速度也快。
/*
ID: thestor1
LANG: C++
TASK: shuttle
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <climits>
#include <cassert>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
struct Trie {
Trie* next[26];
Trie()
{
for (int i = 0; i < 26; ++i)
{
next[i] = NULL;
}
}
};
void insert(Trie *trie, string str)
{
for (int i = 0; i < str.size(); ++i)
{
if (!trie->next[str[i] - '0'])
{
trie->next[str[i] - '0'] = new Trie();
}
trie = trie->next[str[i] - '0'];
}
}
bool search(Trie *trie, string str)
{
for (int i = 0; i < str.size(); ++i)
{
if (!trie->next[str[i] - '0'])
{
return false;
}
trie = trie->next[str[i] - '0'];
}
return true;
}
Trie *trie;
void shuttle(string &best, string &sol, int hole, string ¤t, const string &target)
{
if (current == target)
{
if (best.size() == 0 || sol.size() < best.size())
{
best = sol;
}
return;
}
if (best.size() > 0 && sol.size() >= best.size())
{
return;
}
if (hole - 2 >= 0 && current[hole - 1] == '2' && current[hole - 2] == '1')
{
sol.push_back(hole - 2 + 1 + '0');
if (!search(trie, sol))
{
insert(trie, sol);
current[hole] = '1';
current[hole - 2] = '0';
shuttle(best, sol, hole - 2, current, target);
current[hole - 2] = '1';
current[hole] = '0';
}
// sol.pop_back();
sol = sol.substr(0, sol.size() - 1);
}
if (hole - 1 >= 0 && current[hole - 1] == '1')
{
sol.push_back(hole - 1 + 1 + '0');
if (!search(trie, sol))
{
insert(trie, sol);
current[hole] = '1';
current[hole - 1] = '0';
shuttle(best, sol, hole - 1, current, target);
current[hole - 1] = '1';
current[hole] = '0';
}
// sol.pop_back();
sol = sol.substr(0, sol.size() - 1);
}
if (hole + 1 < current.size() && current[hole + 1] == '2')
{
sol.push_back(hole + 1 + 1 + '0');
if (!search(trie, sol))
{
insert(trie, sol);
current[hole] = '2';
current[hole + 1] = '0';
shuttle(best, sol, hole + 1, current, target);
current[hole + 1] = '2';
current[hole] = '0';
}
// sol.pop_back();
sol = sol.substr(0, sol.size() - 1);
}
if (hole + 2 < current.size() && current[hole + 1] == '1' && current[hole + 2] == '2')
{
sol.push_back(hole + 2 + 1 + '0');
if (!search(trie, sol))
{
insert(trie, sol);
current[hole] = '2';
current[hole + 2] = '0';
shuttle(best, sol, hole + 2, current, target);
current[hole + 2] = '2';
current[hole] = '0';
}
// sol.pop_back();
sol = sol.substr(0, sol.size() - 1);
}
}
int main()
{
trie = new Trie();
ifstream fin("shuttle.in");
ofstream fout("shuttle.out");
int N;
fin>>N;
string initial(2 * N + 1, '0');
for (int i = 0; i < N; ++i)
{
initial[i] = '1';
}
for (int i = N + 1; i < 2 * N + 1; ++i)
{
initial[i] = '2';
}
string target(2 * N + 1, '0');
for (int i = 0; i < N; ++i)
{
target[i] = '2';
}
for (int i = N + 1; i < 2 * N + 1; ++i)
{
target[i] = '1';
}
string best = "", sol = "";
shuttle(best, sol, N, initial, target);
for (int i = 0; i < best.size(); ++i)
{
fout<<(best[i] - '0');
if ((i + 1) % 20 == 0 || i == best.size() - 1)
{
fout<<endl;
}
else
{
fout<<" ";
}
}
fin.close();
fout.close();
return 0;
}