题目
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5641
题目来源:BestCoder#75
简要题意:求是否为合法的解锁序列的。
题解
这是一道小模拟,但是考察了一些边角的细节,还是有点麻烦的。
题目中有几个关键的条件,首先是个数大于 3
然后不能有重复。
最后就是不能跳过没有访问过的点。
我比赛时候的做法是分解为三个函数。
判断最后一个时候需要进行一些判断,我可以建立一张图,对每列每行一个循环做掉,然后对角线特判。
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
// head
bool checkRange(vector<int> &a, int n) {
for (int i = 0; i < n; i++) {
if (a[i] < 1 || a[i] > 9) return false;
}
return true;
}
bool checkDup(vector<int> &a, int n) {
bool vis[15];
memset(vis, 0, sizeof vis);
for (int i = 0; i < n; i++) {
if (vis[a[i]]) return false;
vis[a[i]] = true;
}
return true;
}
int g[5][5];
bool judge(int from, int to, bool vis[15]) {
if (from > to) swap(from, to);
for (int i = 0; i < 3; i++) {
if (g[i][0] == from && g[i][2] == to && !vis[g[i][1]]) return false;
if (g[0][i] == from && g[2][i] == to && !vis[g[1][i]]) return false;
}
if (from == 1 && to == 9 && !vis[5]) return false;
if (from == 3 && to == 7 && !vis[5]) return false;
return true;
}
bool checkPath(vector<int> &a, int n) {
bool vis[15];
memset(vis, 0, sizeof vis);
for (int i = 0; i < n; i++) {
vis[a[i]] = true;
if (i == 0) continue;
if (!judge(a[i-1], a[i], vis)) return false;
}
return true;
}
int main() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
g[i][j] = i*3 + j + 1;
}
}
int t, n, x;
scanf("%d", &t);
while (t--) {
vector<int> a;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &x);
a.push_back(x);
}
if (n < 4 || !checkRange(a, n) || !checkDup(a, n) || !checkPath(a, n)) {
puts("invalid");
} else {
puts("valid");
}
}
return 0;
}
题解2
然后我们也可以构建一个矩阵
g[i][j]:=i,j 的中间有点 g[i][j] 。然后判断就变得比较方便了,对于初始的值要进行一个判断。
代码2
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
// head
int g[15][15];
bool vis[15];
bool judge(int from, int to, bool vis[15]) {
if (from > to) swap(from, to);
return !g[from][to] || vis[g[from][to]];
}
bool check(vector<int> &a, int n) {
memset(vis, 0, sizeof vis);
for (int i = 0; i < n; i++) {
if (a[i] < 1 || a[i] > 9 || vis[a[i]]) return false;
vis[a[i]] = true;
if (i && !judge(a[i-1], a[i], vis)) return false;
}
return true;
}
void init() {
g[1][9] = g[3][7] = g[2][8] = g[4][6] = 5;
g[1][7] = 4;
g[3][9] = 6;
g[7][9] = 8;
g[1][3] = 2;
}
int main() {
init();
int t, n, x;
scanf("%d", &t);
while (t--) {
vector<int> a;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &x);
a.push_back(x);
}
if (n < 4 || !check(a, n)) {
puts("invalid");
} else {
puts("valid");
}
}
return 0;
}