洛谷 P2040 打开所有的灯
2018-01-25 08:06
211 查看
发现自己跑的好优越,只是2^{n}级的复杂度
其实这道题目你会发现其实只需要关心是否会与这盏灯操作一次就够了!
为什么? 其实如果是操作 2 次, 4 次,或者 6 次……其实都是对答案是一样的—根本没有操作! 而 1 , 3 , 5 ,7 ….也就等同于操作一次!
如 5 号灯操作了5下(原来是 开的) 就是:关,开,关,开,关…
结果还是关
那么…我们对于这 9 个格子,只要二进制操作一番就好了,比如:
100111101
就是对于1,4,5,6,7,9这些灯盏操作,那么我们只要记录是否能够完成就好了!
其实这道题目你会发现其实只需要关心是否会与这盏灯操作一次就够了!
为什么? 其实如果是操作 2 次, 4 次,或者 6 次……其实都是对答案是一样的—根本没有操作! 而 1 , 3 , 5 ,7 ….也就等同于操作一次!
如 5 号灯操作了5下(原来是 开的) 就是:关,开,关,开,关…
结果还是关
那么…我们对于这 9 个格子,只要二进制操作一番就好了,比如:
100111101
就是对于1,4,5,6,7,9这些灯盏操作,那么我们只要记录是否能够完成就好了!
#pragma GCC optimize(3) #include <iostream> #include <algorithm> #include <cstring> #include <math.h> #include <stdio.h> #include <queue> #include <vector> #include <string> #include <stack> #include <ctime> #include <set> #include <map> #define fi first #define se second #define P pair<int,int> #define sc scanf #define pi printf #define N 1500 #define M 300005 #define INF 0x3f3f3f3f using namespace std; inline int getmax(int x,int y){return (x>y)?x:y;} inline int getmin(int x,int y){return (x>y)?y:x;} int n,ans=INF,tot,a[13],s[13],how[13]; inline void get(int n) { int cnt=0; memset(s,0,sizeof s); while(n) { s[cnt++]=n%2; n/=2; } } int main(int argc, char const *argv[]) { for(int i=0;i<9;i++) scanf("%d",a+i); for(int used=0;used<(1<<9);used++) // 暴力枚举二进制 { get(used); memset(how,0,sizeof how); for(int i=0;i<9;i++) //算i号的灯盏被操作了多少次! if(s[i]) //9 个格子的打暴力,其实可以变得简洁一些! { if(!i) how[0]++,how[1]++,how[3]++; else if(i==1) how[0]++,how[1]++,how[2]++,how[4]++; else if(i==2) how[1]++,how[2]++,how[5]++; else if(i==3) how[0]++,how[6]++,how[4]++,how[3]++; else if(i==4) how[4]++,how[1]++,how[3]++,how[5]++,how[7]++; else if(i==5) how[4]++,how[5]++,how[2]++,how[8]++; else if(i==6) how[6]++,how[3]++,how[7]++; else if(i==7) how[7]++,how[6]++,how[8]++,how[4]++; else if(i==8) how[5]++,how[7]++,how[8]++; } bool flag=true; for(int i=0;i<9;i++) // 计算是否可行! if(how[i]%2==1 && a[i]) flag=false; else if(how[i]%2==0 && !a[i]) flag=false; if(flag) { tot=0; for(int i=0;i<9;i++) if(s[i]) tot++; ans=getmin(tot,ans); } } // printf("%d\n",ans); }
相关文章推荐
- 洛谷 P2040 打开所有的灯
- 洛谷 P2040 打开所有的灯
- 用javascript实现始终保持打开同一个子窗口以及关闭父窗口同时自动关闭所有子窗口
- wall命令_Linux wall 命令用法详解:向系统当前所有打开的终端上输出信息
- iOS 开发之一个挺操蛋的问题,Xcode刚打开工程文件展示区显示不出所有文件。
- QT 应用程序关闭某个窗口时,关闭打开的所有其他窗口并退出程序 【转】
- QT 关闭主窗口,触发关闭所有打开的窗口
- 表服务器无法打开与报表服务器数据库的连接。所有请求和处理都要求与数据库建立连接。
- Android 获取所有已安装应用信息(图标,名称,版本号,包) ,并在自己程序打开某个应用
- 列举linux进程打开的所有文件
- PHP打开所有报错
- _flushall对所有已经打开的流flush
- 3D打印的钥匙几乎能打开所有的锁
- (转载)表服务器无法打开与报表服务器数据库的连接。所有请求和处理都要求与数据库建立连接。
- 刚装的系统发现所有帮助文档不能够打开了??
- 如何使用 base 标签使页面中的所有标签在新窗口中打开
- 获取软件所有快捷方式名称,判断本地是否安装,并打开
- 获取已打开的所有记事本的标题
- linux 查看所有打开so档的进程
- "不是所有工作区中的窗口无法打开"错误消息(Not all of the Windows in the workspace could be open)