Catalog
题解 P1312 【Mayan游戏】

查看原题请戳这里

感觉地图就$5\times 7$这么大,直接爆搜好了 (于是就拿了$60$分)).

像这样的搜索加模拟题,我推荐把每一步都分成单独的函数去写,虽然步骤比较多,但是实现起来并不难,这里就不再赘述了,直接讲一下剪枝(防止重复搜到同样的状态).

  1. 字符串+Map

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    bool has(long long k)
    {
    int p = 0; string s;
    s.push_back(k);
    for(re int i = 1; i <= 5; i++)
    for(re int j = 1; j <= t[i] + 1; j++)
    s.push_back(Map[i][j]);
    s.push_back(k);
    if(ma.find(s) != ma.end()) return true;
    ma[s] = 1;
    return false;
    }
  2. hash + set

    1
    2
    3
    4
    5
    6
    7
    8
    long long a[6] = {0},b = 0,tj = se.size();
    for(re int i = 1; i <= 5; i++)
    for(re int j = 1; j <= t[i] + 1; j++)
    a[i] = a[i] * 13331 + map[i][j],b = b * 13331 + map[i][j];
    for(re int i = 1; i <= 5; i++) a[0] = a[0] * 13331 + a[i];
    se.insert(b);
    if(se.size() == tj) return true;
    return false;

code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<set>
#include<algorithm>
#define ll long long
#define re register
#define qwq printf("qwq\n");
#define INF 0x7fffffff

using namespace std;

long long read()
{
register long long x = 0,f = 1;register char ch;
ch = getchar();
while(ch > '9' || ch < '0'){if(ch == '-') f = -f;ch = getchar();}
while(ch <= '9' && ch >= '0'){x = x * 10 + ch - 48;ch = getchar();}
return x * f;
}

long long n,m,x,t[15],p[15],flag,map[15][15],del[15][15];

set<long long> se;

struct answer{
long long x,y,g;
}ans[100005];

void make_ans(long long k,long long i,long long j,long long g)
{
ans[k].x = i - 1; ans[k].y = j - 1; ans[k].g = g;
}

void down(long long x)
{
long long cnt = 0,tmp;
for(re int i = 1; i <= 7; i++) if(map[x][i]) tmp = map[x][i], map[x][i] = 0, map[x][++cnt] = tmp;
t[x] = cnt;
}

bool has(long long k)
{
long long a[6] = {0},b = k,tj = se.size();
for(re int i = 1; i <= 5; i++)
for(re int j = 1; j <= t[i] + 1; j++)
b = b * 13331 + map[i][j];
se.insert(b);
if(se.size() == tj) return true;
return false;
}

bool delet()
{
bool changed = false;
for(re int i = 1; i <= 5; i++)
{
long long j = 0,cnt;
while(j < t[i])
{
j++; cnt = 1;
while(map[i][j] == map[i][j + 1]) j++, cnt++;
if(cnt >= 3) for(re int k = 1; k <= cnt; k++) del[i][j - k + 1] = 1;
if(cnt >= 3) changed = true;
}
}
for(re int i = 1; i <= 7; i++)
{
long long j = 0,cnt;
while(j < 5)
{
j++; cnt = 1;
if(t[j] < i) continue;
while(map[j][i] == map[j + 1][i] && t[j + 1] >= i) j++,cnt++;
if(cnt >= 3) for(re int k = 1; k <= cnt; k++) del[j - k + 1][i] = 1;
if(cnt >= 3) changed = true;
}
}
for(re int i = 1; i <= 5; i++)
{
for(re int j = 1; j <= t[i]; j++) if(del[i][j]) map[i][j] = 0,del[i][j] = 0;
down(i);
}
if(changed) delet();
return changed;
}

bool rm(long long x,long long y,long long g)
{
if(g == 1)
{
if(x == 5) return false;
swap(map[x][y], map[x + 1][y]);
down(x); down(x + 1);
}
if(g == -1)
{
if(x == 1) return false;
swap(map[x][y], map[x - 1][y]);
down(x); down(x - 1);
}
delet();
return true;
}

bool check(long long k)
{
long long judge = true;
for(re int i = 1; i <= 5; i++) if(t[i] != 0) judge = false;
if(judge)
{
flag = true;
for(re int i = 1; i < k; i++) printf("%lld %lld %lld\n",ans[i].x,ans[i].y,ans[i].g);
}
if(k > n) return true;
return judge;
}

void dfs(long long k)
{
if(flag) return ;
if(check(k)) return ;
if(has(k)) return;
long long tmp[9][9],tm[9];
for(re int i = 1; i <= 5; i++) tm[i] = t[i];
for(re int i = 1; i <= 5; i++)
for(re int j = 1; j <= 7; j++)
tmp[i][j] = map[i][j];
for(re int i = 1; i <= 5; i++)
for(re int j = 1; j <= tm[i]; j++)
{
if(rm(i,j,1)) make_ans(k,i,j,1), dfs(k + 1);
for(re int i = 1; i <= 5; i++)
for(re int j = 1; j <= 7; j++)
map[i][j] = tmp[i][j];
for(re int i = 1; i <= 5; i++) t[i] = tm[i];
if(rm(i,j,-1)) make_ans(k,i,j,-1), dfs(k + 1);
for(re int i = 1; i <= 5; i++)
for(re int j = 1; j <= 7; j++)
map[i][j] = tmp[i][j];
for(re int i = 1; i <= 5; i++) t[i] = tm[i];
}
}

int main()
{
n = read();
for(re int i = 1; i <= 5; i++)
{
x = read();
while(x) map[i][++t[i]] = x,x = read();
}
dfs(1);
if(!flag) printf("-1\n");
return 0;
}
Author: wflight
Link: http://yoursite.com/2019/11/02/题解-P1312-【Mayan游戏】/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶

Comment