目录
PuzzleBlocks
Steam游戏,把异形块拼接成指定图形,可以旋转不能翻转。
Egypt
(9)
(14)
(15)
(18)
(20)
(21)
(24)
(27)
(28)
(30)
Greece
付费解锁
平铺楼梯区域
出自算法谜题:
代码:
#include<iostream>
#include<vector>
#include <iomanip>
using namespace std;
vector<vector<int>> v66 =
{ { 1, 0, 0, 0, 0, 0},
{ 1, 1, 0, 0, 0, 0},
{ 6, 6, 2, 0, 0, 0},
{ 6, 5, 2, 2, 0, 0},
{ 7, 5, 5, 4, 3, 0},
{ 7, 7, 4, 4, 3, 3}
};
vector<vector<int>> v99 =
{
{1, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 1, 1, 0, 0, 0, 0, 0, 0, 0, },
{ 5, 5, 2, 0, 0, 0, 0, 0, 0, },
{ 6, 5, 2, 2, 0, 0, 0, 0, 0, },
{ 6, 6, 4, 4, 3, 0, 0, 0, 0, },
{ 8, 7, 7, 4, 3, 3, 0, 0, 0, },
{ 8, 8, 7, 12, 12, 10, 10, 0, 0, },
{ 15, 14, 14, 13, 12, 11, 10, 9, 0, },
{ 15, 15, 14, 13, 13, 11, 11, 9, 9, },
};
vector<vector<int>> v62 =
{ { 1, 1},
{ 1, 2},
{ 2, 2},
{ 3, 3},
{ 3, 4},
{ 4, 4}
};
vector<vector<int>> v92 =
{ { 1, 1},
{ 1, 2},
{ 2, 2},
{ 3, 3},
{ 3, 4},
{ 4, 4},
{ 5, 5},
{ 5, 6},
{ 6, 6}
};
vector<vector<int>> v22 =
{ { 1, 0},
{ 1, 1}
};
vector<vector<int>> v32 =
{ { 1, 2, 2},
{ 1, 1, 2}
};
void addn(vector<vector<int>> &v, int n)
{
for (auto& vi : v) {
for (auto& vj : vi)if (vj)vj += n;
}
}
int calNum(int n)
{
return (n + 1) * n / 6;
}
//2个vector拼接起来
template<typename T>
vector<T> join(vector<T>& v1, vector<T>& v2)
{
vector<T>ans(v1.size() + v2.size());
copy(v1.begin(), v1.end(), ans.begin());
copy(v2.begin(), v2.end(), ans.begin() + v1.size());
return ans;
}
template<typename T>
vector<vector<T>> join2(vector<vector<T>>& v1, vector<vector<T>>& v2)
{
vector<vector<T>>ans;
ans.resize(v1.size());
for (int i = 0; i < v1.size(); i++)ans[i] = join(v1[i], v2[i]);
return ans;
}
bool getNum(int n, vector<vector<int>>&v)
{
if (n < 2 || n>30)return false;
if (n % 3 == 1)return false;
if (n % 3 == 0) {
if (n == 3)return false;
if (n == 6)v = v66;
else if (n == 9)v = v99;
else if (n % 6 == 0) {
getNum(n - 6, v);
for (int i = 0; i < n-6; i++)for (int j = 0; j < 6; j++)v[i].push_back(0);
vector<vector<int>>vd;
vd.resize(6);
int k = calNum(n - 6);
for (int i = 0; i < (n-6)/2; i++) {
vector<vector<int>> v62tmp = v62;
addn(v62tmp, k);
k += 6 * 2 / 3;
vd = join2(vd, v62tmp);
}
vector<vector<int>> v66tmp = v66;
addn(v66tmp, k);
vd = join2(vd, v66tmp);
v = join(v, vd);
}
else {
getNum(n - 9, v);
for (int i = 0; i < n - 9; i++)for (int j = 0; j < 9; j++)v[i].push_back(0);
vector<vector<int>>vd;
vd.resize(9);
int k = calNum(n - 9);
for (int i = 0; i < (n - 9) / 2; i++) {
vector<vector<int>> v92tmp = v92;
addn(v92tmp, k);
k += 9 * 2 / 3;
vd = join2(vd, v92tmp);
}
vector<vector<int>> v99tmp = v99;
addn(v99tmp, k);
vd = join2(vd, v99tmp);
v = join(v, vd);
}
}
else {
if (n == 2)v = v22;
else {
getNum(n - 2, v);
for (int i = 0; i < n - 2; i++)for (int j = 0; j < 2; j++)v[i].push_back(0);
vector<vector<int>>vd;
vd.resize(2);
int k = calNum(n - 2);
for (int i = 0; i < (n - 2) / 3; i++) {
vector<vector<int>> v32tmp = v32;
addn(v32tmp, k);
k += 3 * 2 / 3;
vd = join2(vd, v32tmp);
}
vector<vector<int>> v22tmp = v22;
addn(v22tmp, k);
vd = join2(vd, v22tmp);
v = join(v, vd);
}
}
}
#define CIN(x) while (!(cin >> x)) { \
cin.clear(); \
cin.ignore(); \
}
#define CIN2(x, y) CIN(x)CIN(y)
#define CIN3(x, y, z) CIN(x)CIN(y)CIN(z)
int main()
{
vector<vector<int>> v;
getNum(24,v);
for (int i = 0; i < v.size(); i++) {
for (int j = 0; j < v.size(); j++)cout << setw(2)<< v[i][j] << " ";
cout << endl;
}
return 0;
}
优化后代码:
#include<iostream>
#include<vector>
#include <iomanip>
using namespace std;
#define FvecJoin Basic::join //2个vector(一维或2维)左右拼接起来
void addn(vector<vector<int>> &v, int n)
{
for (auto& vi : v) {
for (auto& vj : vi)if (vj)vj += n;
}
}
int calNum(int n)
{
return (n + 1) * n / 6;
}
vector<vector<int>> v66 =
{ { 1, 0, 0, 0, 0, 0},
{ 1, 1, 0, 0, 0, 0},
{ 6, 6, 2, 0, 0, 0},
{ 6, 5, 2, 2, 0, 0},
{ 7, 5, 5, 4, 3, 0},
{ 7, 7, 4, 4, 3, 3}
};
vector<vector<int>> v99 =
{
{1, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 1, 1, 0, 0, 0, 0, 0, 0, 0, },
{ 5, 5, 2, 0, 0, 0, 0, 0, 0, },
{ 6, 5, 2, 2, 0, 0, 0, 0, 0, },
{ 6, 6, 4, 4, 3, 0, 0, 0, 0, },
{ 8, 7, 7, 4, 3, 3, 0, 0, 0, },
{ 8, 8, 7, 12, 12, 10, 10, 0, 0, },
{ 15, 14, 14, 13, 12, 11, 10, 9, 0, },
{ 15, 15, 14, 13, 13, 11, 11, 9, 9, },
};
vector<vector<int>> v62 =
{ { 1, 1},
{ 1, 2},
{ 2, 2},
{ 3, 3},
{ 3, 4},
{ 4, 4}
};
vector<vector<int>> v92 =
{ { 1, 1},
{ 1, 2},
{ 2, 2},
{ 3, 3},
{ 3, 4},
{ 4, 4},
{ 5, 5},
{ 5, 6},
{ 6, 6}
};
vector<vector<int>> v22 =
{ { 1, 0},
{ 1, 1}
};
vector<vector<int>> v23 =
{ { 1, 2, 2},
{ 1, 1, 2}
};
#define GETNUM(x,y) if(r==x && c==y)return v##x##y
vector<vector<int>> getNum(int r, int c)
{
GETNUM(6, 6);
GETNUM(9, 9);
GETNUM(6, 2);
GETNUM(9, 2);
GETNUM(2, 2);
GETNUM(2, 3);
return vector<vector<int>>();
}
bool getNum(int n, vector<vector<int>>&v)
{
if (n < 2 || n>30)return false;
if (n % 3 == 1)return false;
if (n == 3 || n == 5)return false;
if (n == 2)v = v22;
else if (n == 6)v = v66;
else if (n == 9)v = v99;
else {
int d = n % 3 ? 2 : n % 6 + 6;
getNum(n - d, v);
for (auto& vi : v)for (int j = 0; j < d; j++)vi.push_back(0);
vector<vector<int>>vd;
vd.resize(d);
int k = calNum(n - d);
if (n % 3 == 0) {
for (int i = 0; i < (n - d) / 2; i++) {
vector<vector<int>> vtmp = getNum(d, 2);
addn(vtmp, k);
k += d * 2 / 3;
vd = FvecJoin(vd, vtmp);
}
}
else {
for (int i = 0; i < (n - d) / 3; i++) {
vector<vector<int>> vtmp = getNum(d, 3);
addn(vtmp, k);
k += 2;
vd = FvecJoin(vd, vtmp);
}
}
vector<vector<int>> vtmp = getNum(d, d);
addn(vtmp, k);
vd = FvecJoin(vd, vtmp);
v = FvecJoin(v, vd);
}
}
#define CIN(x) while (!(cin >> x)) { \
cin.clear(); \
cin.ignore(); \
}
int main()
{
int n;
CIN(n);
vector<vector<int>> v;
getNum(n, v);
int num = calNum(n);
vector<vector<pair<int, int>>> ans;
ans.resize(num + 1);
for (int i = 0; i < v.size(); i++) {
for (int j = 0; j < v.size(); j++)cout << setw(2) << v[i][j] << " ";
cout << endl;
}
return 0;
}
运行示例: