作業瘋了 - 部分題目代碼

之前看到老番茄玩所以關注了一下這個遊戲……
一開始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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章