CTU Open 2013 的一道题
题意在另一份报告:http://blog.csdn.net/d_xcj/article/details/52752139分析:
和之前说的差不多,是一道比较复杂的搜索和模拟,主要是模拟比较烦人,写起来很长,要注意很多细节。
我的想法很简单,先预处理出任意两种方块能组成的所有形状(状态不是很多),然后判断给出的2个yellow pots能组成的形状另外2个red pots是不是也能组成一样的形状,然后顺便把答案也记忆化。
预处理的时候我是先把pot1压在边上,然后把pot2放到pot1周围,pot1、pot2的8种形态(初态、3次旋转、初态的翻转,再来3次旋转)都来一遍,然后把pot2压在边上,把pot1放到pot2周围。。。。(感觉重复还是会挺多 = =?,不过时限给得很宽,一般不会超时)
不擅长写这么长的代码 QAQ,应该有更好的解法,不过没想出来
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> VI;
const int N = 12;
const char POT[] = "FILNPTUVWXYZ";
vector<string> pot[N];
void table()
{
pot[0].push_back(" ##");
pot[0].push_back("## ");
pot[0].push_back(" # ");
pot[1].push_back("#");
pot[1].push_back("#");
pot[1].push_back("#");
pot[1].push_back("#");
pot[1].push_back("#");
pot[2].push_back("# ");
pot[2].push_back("# ");
pot[2].push_back("# ");
pot[2].push_back("##");
pot[3].push_back(" #");
pot[3].push_back(" #");
pot[3].push_back("##");
pot[3].push_back("# ");
pot[4].push_back("##");
pot[4].push_back("##");
pot[4].push_back("# ");
pot[5].push_back("###");
pot[5].push_back(" # ");
pot[5].push_back(" # ");
pot[6].push_back("# #");
pot[6].push_back("###");
pot[7].push_back("# ");
pot[7].push_back("# ");
pot[7].push_back("###");
pot[8].push_back("# ");
pot[8].push_back("## ");
pot[8].push_back(" ##");
pot[9].push_back(" # ");
pot[9].push_back("###");
pot[9].push_back(" # ");
pot[10].push_back(" #");
pot[10].push_back("##");
pot[10].push_back(" #");
pot[10].push_back(" #");
pot[11].push_back("## ");
pot[11].push_back(" # ");
pot[11].push_back(" ##");
}
set<VI> smemery[N][N];
int ansmemery[N][N][N][N];
bool board[N][N];
void rotate(int &si, int &ei, int &sj, int &ej, bool &isrl)
{
swap(si, ei);
swap(si, sj);
swap(ei, ej);
isrl = !isrl;
}
void reverse(int &sj, int &ej)
{
swap(sj, ej);
}
void GetPotConfig(int id, int &si, int &ei, int &sj, int &ej, bool &isrl)
{
si = 0;
ei = pot[id].size() - 1;
sj = 0;
ej = pot[id][0].size() - 1;
isrl = true;
}
bool fill_p(int id, int si, int ei, int sj, int ej, bool isrl, int x, int y, int record = -1, bool rot = false)
{
bool ok = true;
int top = -1;
static pii stk[N];
int counter1 = si < ei ? 1 : -1;
int counter2 = sj < ej ? 1 : -1;
ei += counter1;
ej += counter2;
int i, j, tx, ty;
for(i = si, tx = x; i != ei && ok; i += counter1, tx++)
for(j = sj, ty = y; j != ej; j += counter2, ty++)
{
if(isrl && pot[id][i][j] == '#')
{
if(board[tx][ty])
{
ok = false;
break;
}
board[tx][ty] = true;
stk[++top] = pii(tx, ty);
}
else if(!isrl && pot[id][j][i] == '#')
{
if(board[tx][ty])
{
ok = false;
break;
}
board[tx][ty] = true;
stk[++top] = pii(tx, ty);
}
}
if(record >= 0)
{
if(ok)
{
vector<int> sta;
si = sj = 1e9;
ei = ej = 0;
isrl = true;
for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
{
if(board[i][j])
{
si = min(si, i);
sj = min(sj, j);
ei = max(ei, i);
ej = max(ej, j);
}
}
int x = si < ei ? 1 : -1;
int y = sj < ej ? 1 : -1;
int limit_i = ei + x;
int limit_j = ej + y;
sta.clear();
for(i = si; i != limit_i; i += x)
{
for(j = sj; j != limit_j; j += y)
{
if(isrl && board[i][j]) sta.push_back(true);
else if(!isrl && board[j][i]) sta.push_back(true);
else sta.push_back(false);
}
}
sta.push_back(abs(ej - sj) + 1);
if(id > record) swap(record, id);
smemery[id][record].insert(sta);
}
while(top != -1)
{
board[stk[top].first][stk[top].second] = false;
top--;
}
}
return ok;
}
void _init(int a, int b)
{
for(int k = 0; k < 2; k++)
{
int si, ei, sj, ej;
bool isrl;
int si2, sj2, ei2, ej2;
bool isrl2;
GetPotConfig(a, si, ei, sj, ej, isrl);
GetPotConfig(b, si2, ei2, sj2, ej2, isrl2);
int limit = max(ei2, ej2) + 1;
for(int i = 0; i < 8; i++)
{
for(int k = 0; k <= limit; k++)
{
memset(board, false, sizeof(board));
fill_p(a, si, ei, sj, ej, isrl, k, 0);
GetPotConfig(b, si2, ei2, sj2, ej2, isrl2);
for(int j = 0; j < 8; j++)
{
int limit_x = abs(ei - si) + 2;
int limit_y = abs(ej - sj) + 2;
for(int x = 0; x < limit_x; x++)
for(int y = 0; y < limit_y; y++)
{
fill_p(b, si2, ei2, sj2, ej2, isrl2, x, y, a, !isrl);
}
rotate(si2, ei2, sj2, ej2, isrl2);
if(j == 3) reverse(sj2, ej2);
}
}
rotate(si, ei, sj, ej, isrl);
if(i == 3) reverse(sj, ej);
}
swap(a, b);
}
}
void init()
{
for(int i = 0; i < N; i++)
for(int j = i; j < N; j++)
{
_init(i, j);
}
}
void solve(char A, char B, char C, char D)
{
int a = lower_bound(POT, POT + N, A) - POT;
int b = lower_bound(POT, POT + N, B) - POT;
int c = lower_bound(POT, POT + N, C) - POT;
int d = lower_bound(POT, POT + N, D) - POT;
if(a > b) swap(a, b);
if(c > d) swap(c, d);
int flag = ansmemery[a][b][c][d];
if(flag == 1) puts("NO");
else if(flag == 2) puts("YES");
else
{
set<VI>::iterator it;
for(it = smemery[a][b].begin(); it != smemery[a][b].end(); ++it)
{
if(smemery[c][d].count(*it))
{
flag = 1;
break;
}
}
ansmemery[a][b][c][d] = ansmemery[c][d][a][b] = flag + 1;
if(flag) puts("YES");
else puts("NO");
}
}
int main()
{
table();
init();
char a, b, c, d;
while(scanf(" %c%c %c%c", &a, &b, &c, &d) != EOF)
{
solve(a, b, c, d);
}
return 0;
}