费解的开关:
枚举情况求最值、最优解的套路:
卡壳原因:套路的细节不熟悉
1.1
在枚举情况前,变量设置res,求最小值要设置一个大的数0x3f3f3f3f,最大值要设置小的数
枚举的每一种情况里要设置一个变量来统计这种情况的值,数量,末尾要和res比较
枚举完后再输出
1.2如果枚举的是操作情况,在枚举前要对被操作对象备份,操作后要还原对象
int res = 0x3f3f3f3f; memcpy(backup,f,sizeof f); // 错误:备份的位置错误,应该输入后再备份,对备份的位置不熟悉 for(int op = 0;op < 32;op++){ int cnt = 0; for(int i = 0;i < 5;i++)//卡壳,不熟悉位运算枚举开关点按情况的操作 { if(op >> i & 1){ turn(0,i); // 错误,这题下表用了0~4,对第一行操作应该是0才对,没有确认好下标 //卡壳,不熟悉位运算枚举里的坐标获取; cnt++; } } for(int i = 0;i < 4;i++){ for(int j = 0;j < 5;j++){ if(f[i][j] == '0'){ turn(i+1,j); cnt++; } } } bool all_turn_on = true; for(int i = 0;i < 5;i++){ if(f[4][i] == '0') all_turn_on = false; } if(all_turn_on) res = min(res,cnt); // 错误:res应该是在所有可能都枚举完后才判断是否没有符合题意的res要赋值-1的 memcpy(f,backup,sizeof f); } if(res > 6) res = -1; cout << res << endl;
输入数据与变量数据类型选择的套路
卡壳原因,见过没总结,踩陷阱了,题目输入的点阵之间没有空格,我没有注意到这个点,用int读入数据,结果直接把整一行当做一个数字读入了
如果输入的数据之间没有空格,要把数据当作字符来读取,不能用整型或浮点型来读取
char f[N][N]; for(int i = 0;i < 5;i++){ for(int j = 0;j < 5;j++){ cin >> f[i][j]; } }
- 坐标移动的枚举套路
卡壳原因:不熟悉套路的细节,没有判断边界
int dx[] = {1,-1,0,0,0},dy[] = {0,0,1,-1,0}; for(int i = 0;i < 5;i++){ int a = x + dx[i]; int b = y + dy[i]; if(a < 0 || a >=5 || b < 0 || b >=5)continue; // 错误:没有判断边界,对坐标移动的相关注意点不熟 // if (a < 0 || a >= 5 || b < 0 || b >= 5) continue; // 在边界外,直接忽略即可 f[a][b] ^= 1; }