解题思路:

        模拟 + DFS。其中最巧妙的就是如何记录开关的某个组合出现过,当然是 Hash 值啦。


参考代码:

#include<bits/stdc++.h> /* 一共 112 个组合,5 ms 哟 */
using namespace std;
const int SIZE = 23277;         /*   随便开个数啦   >v<  */

bool Light[10]; 
bool Status[SIZE]; int Index;   /*   存储开关的某个状态  */

/*   用结构体存储开关组合,用作排序输出   */
struct Ans {
	char num[10];
} ans[144];

/*   模拟灯   */
void OPT(char button[], int num) {
	/*  改变灯  */
	if (num == 1)      Light[2] = !Light[2], Light[4] = !Light[4];
	else if (num == 2) Light[1] = !Light[1], Light[3] = !Light[3], Light[5] = !Light[5];
	else if (num == 3) Light[2] = !Light[2], Light[6] = !Light[6];
	else if (num == 4) Light[1] = !Light[1], Light[5] = !Light[5], Light[7] = !Light[7];
	else if (num == 5) Light[2] = !Light[2], Light[4] = !Light[4], Light[6] = !Light[6], 
	                   Light[8] = !Light[8];
	else if (num == 6) Light[3] = !Light[3], Light[5] = !Light[5], Light[9] = !Light[9];
	else if (num == 7) Light[4] = !Light[4], Light[8] = !Light[8];
	else if (num == 8) Light[5] = !Light[5], Light[7] = !Light[7], Light[9] = !Light[9];
	else if (num == 9) Light[6] = !Light[6], Light[8] = !Light[8];
	
	/* 改变开关 */
	if (button[num - 1] == '1')
		button[num - 1] = '0';
	else
		button[num - 1] = '1';
}

/*   Hash函数计算开关某个状态对应的一个值   */
int  Hash(char button[]) {
	int hash = 0;
	for (int i = 1; i < 10; i++)
		hash = hash * i + button[i - 1] + 7;
	return hash % 16529; /* 16529 是一个素数 */
}

/*     判断当前灯是否亮了 4 盏    */
bool Judge() {
	int total = 0;
	for (int i = 1; i < 10; i++)
		if (Light[i])
			total++;
	return total == 4;
}

void DFS(char now[]) {
	if (Judge()) {
		strcpy(ans[Index++].num, now); return;
	}
	/*   每个按钮都一遍   */
	for (int button = 1; button < 10; button++) {
		OPT(now, button);                   /*     按下去.jpg     */
		int StatusValue = Hash(now);        /*   计算开关状态值   */
		if (!Status[StatusValue]) {
			Status[StatusValue] = true;
			DFS(now);                       /*     继续到处按     */
		}
		OPT(now, button);                   /*  回溯  */
	}
}

bool cmp(Ans ans1, Ans ans2) {
	return strcmp(ans1.num, ans2.num) < 0;
}

int main() {
	/*clock_t Sta = clock();*/
	char init[] = "000000000";              /*  初始状态全关闭  */

	Status[Hash(init)] = true; DFS(init);

	sort(ans, ans + Index, cmp);

	for (int i = 0; i < Index; i++)
		printf("%s\n", ans[i].num);

	/*clock_t End = clock();
	cout << (double)(End - Sta) / CLOCKS_PER_SEC << endl;*/
}


点赞(0)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论