之前看到老番茄玩所以關注了一下這個遊戲……
一開始bug很多,結果和室友直播就,經常切出來寫代碼……
分享幾個題吧。
點燈問題
點燈問題的話這個已經是被很多人研究過的問題了
https://github.com/pmneila/Lights-Out
之前想寫分析的但是沒有成功orz
簡單的操作是如果行列有奇數的話,先把最中間那一列點亮然後再調整。
數字
1-9組成五位數減四位數,得到33333.
int main()
{
for (int i = 33333; i < 50000; i++) {
int t = i - 33333;
string s = to_string(i) + to_string(t);
sort(s.begin(), s.end());
if (s == "123456789")
cout << i << " - " << t << endl;
}
return 0;
}
倒水
就,杯子來回倒水使得平分那題。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <bitset>
#include <vector>
#include <string>
#include <set>
#include <queue>
#include <stack>
#include <assert.h>
#include <algorithm>
#include <string>
using namespace std;
#define ll long long
// 杯子容量
vector<int> cups({ 8, 5, 3 });
// 把i杯裏的水倒入j
vector<int> pour(vector<int> before, int i, int j) {
int all = before[i] + before[j];
if (all > cups[j]) {
before[j] = cups[j];
before[i] = all - cups[j];
}
else {
before[i] = 0;
before[j] = all;
}
return before;
}
int main()
{
const int waternum = 8;
// 初始水位
vector<int> waterbegin({ waternum, 0, 0 });
// 記錄是否訪問過
set<vector<int>> rec;
// 記錄前一個數據
map<vector<int>, vector<int>> before;
queue<vector<int>> que;
que.push(waterbegin);
vector<int> last; // 記錄結束狀態
while (!que.empty()) {
vector<int> water = que.front();
que.pop();
auto s = rec.find(water);
if (s != rec.end()) continue;
if (water[0] * 2 == waternum || water[1] * 2 == waternum || water[2] * 2 == waternum) {
last = water;
break;
}
// pour water in cup[i] to cup[j]
for (int i = 0; i < 3; i++) {
if (water[i] == 0) continue;
for (int j = 0; j < 3; j++) {
if (i == j || water[j] == cups[j]) continue;
auto newwater = pour(water, i, j);
if (rec.find(newwater) != rec.end()) continue;
assert(newwater != water);
que.push(newwater);
before[newwater] = water;
}
}
rec.insert(water);
}
// 倒着輸出
stack<vector<int>> mystack;
while (last != waterbegin) {
mystack.push(last);
last = before[last];
}
while (!mystack.empty()) {
auto t = mystack.top();
mystack.pop();
cout << t[0] << t[1] << t[2] << endl;
}
return 0;
}
蠟燭照明
對於一個N*M的格子,每個蠟燭可以照亮十字形的五個格子。求問怎麼擺放。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <bitset>
#include <vector>
#include <string>
#include <set>
#include <queue>
#include <stack>
#include <assert.h>
#include <algorithm>
#include <string>
using namespace std;
#define ll long long
class board {
public:
vector<vector<int>> lighted;
int lightnum = 0;
board() : lighted(6, vector<int>(7, 0)) {}
void setlight(int x, int y) {
lightnum++;
lighted[x][y] = 2;
int setX[] = { 1, -1, 0, 0 };
int setY[] = { 0, 0, 1, -1 };
for (int i = 0; i < 4; i++) {
int newX = x + setX[i];
int newY = y + setY[i];
if (newX < 0 || newY < 0 || newX >= 6 || newY >= 7) continue;
lighted[newX][newY] = 1;
}
}
bool search() {
if (lightnum > 11) return false;
bool setted = true;
int x, y;
for (int i = 0; i < 6; i++) {
if (!setted) break;
for (int j = 0; j < 7; j++) {
if (!setted) break;
if (lighted[i][j] == 0) {
setted = false;
x = i;
y = j;
break;
}
}
}
if (setted) {
print();
return true;
}
int setX[] = { 1, -1, 0, 0, 0 };
int setY[] = { 0, 0, 0, 1, -1 };
for (int i = 0; i < 5; i++) {
int newX = x + setX[i];
int newY = y + setY[i];
if (newX < 0 || newY < 0 || newX >= 6 || newY >= 7) continue;
if (lighted[newX][newY] == 1) continue;
class board newboard = *this;
newboard.setlight(newX, newY);
newboard.search();
}
return false;
}
void print() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (lighted[i][j] == 2) cout << "O";
else cout << '.';
}
cout << endl;
}
cout << endl;
}
};
int main()
{
class board myboard;
myboard.search();
return 0;
}