洛谷歷險記2

遇到一個有意思的題目P1008,先貼代碼

#include <iostream>
#include <cmath>
#include <iomanip>


using namespace std;

int result[9];
int used[9];

void test() {
	int num1 = result[0] * 100 + result[1] * 10 + result[2];//按位獲得值
	int num2 = result[3] * 100 + result[4] * 10 + result[5];
	int num3 = result[6] * 100 + result[7] * 10 + result[8];
	/*cout << num1 << " " << num2 << " " << num3 << endl;*/
	if (num1 * 6 == num2 * 3 && num1*6 == num3 * 2) {//注意不能用三值相等若是a==b==c,則會令右邊爲邏輯值
		cout << num1 << " " << num2 << " " << num3 << endl;
	}

}

void test1() {
	cout << (1 == 0 == 0);//返回1,標識該過程是右往左,右邊得1,再跟1比較得1
}

void dfs(int count) {
	if (count == 9) {//當選中9個值,進入判定區
		test();
		return;
	}
	for (int i = 0; i < 9; i++)
	{
		if (used[i] != 1) {//未被使用
			used[i] = 1;//將其標記
			result[count] = i + 1;//放入結果集
			dfs(count+1);//樹延伸向下一個節點。!!:不能用count++,否則無法回溯。
			used[i] = 0;//當該路徑不成功則將節點回溯
		}
	}
	return;
}


int main() {
	//另外一套,暴力枚舉
	//for (int i = 192; i < 333; i++) {
	//	int i2 = i * 2;
	//	int i3 = i * 3;
	//	//cout << i<<endl;
	//	if ((i / 100 + i / 10 % 10 + i % 10 + i2 / 100 + i2 / 10 % 10 + i2 % 10 + i3 / 100 + i3 / 10 % 10 + i3 % 10 == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9) && ((i / 100) * (i / 10 % 10) * (i % 10) * (i2 / 100) * (i2 / 10 % 10) * (i2 % 10) * (i3 / 100) * (i3 / 10 % 10) * (i3 % 10) == (1) * (2) * (3) * (4) * (5) * (6) * (7) * (8) * (9))) {
	//		cout << i << " " << i2 << " " << i3 << endl;
	//	}
	//}
	for (int i = 0; i < 9; i++)//初始化
	{
		result[i] = 0;
		used[i] = 0;
	}
	dfs(0);
	test();
	//test1();
	return 0;
}

該題在小子看來有兩種方向:①暴力枚舉 ②回溯

首先說枚舉,枚舉的話,由題目給出的提示,我們可以知道第一個值最小值是192,最大不能打過999/3,逐個遍歷,檢索是否滿足1~9全部出現,運用了題目討論區一個不錯的比較方式,將集合內的值相加相乘值唯一,則爲相同集合(未經數學嚴格證明)。

再來,是回溯,深度優先,得到滿足1~9皆出現的序列,再驗證是否符合1:2:3,其實與上面的方法方向相反,但在我看來,也是一種枚舉。

p1424

 

可以先將能湊出來的整數排除掉,再運算剩餘部分

摘的別人代碼,說下思想,大概就是一開始的日子,先-7,-7。。直到餘下的日子不足7天在分析,餘下的日子會出現哪些情況減少工作日

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章