USACO 2.2 Party Lamps 高能等效+规律枚举
Posted Captain_Von
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了USACO 2.2 Party Lamps 高能等效+规律枚举相关的知识,希望对你有一定的参考价值。
题在这:https://www.luogu.org/problem/show?pid=1468#sub
按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄灭,本来是关着的灯被点亮。
按钮2:当按下此按钮,将改变所有奇数号的灯。
按钮3:当按下此按钮,将改变所有偶数号的灯。
按钮4:当按下此按钮,将改变所有序号是3*K+1(K>=0)的灯。例如:1,4,7...
此题关键:找到4个按钮之间的关系,可发现最终状态只有少数(可枚举的)几种,又:四个操作的影响周期取最小公倍数后,发现 6个灯为一个变化周期,不管如何按按钮,最终N个灯的状态均是以6个灯为基本单位,N/6为循环次数的循环序列
一、首先,从基本操作入手,随意搭配四个按钮,且每种按钮只能使用一次,可发现:(只考虑6个灯,0表示灯灭,1表示灯亮)
1 2 3 4
按1 ====》0 0 0 0 0 0
按2 ====》0 1 0 1 0 1
按3 ====》1 0 1 0 1 0
按4 ====》0 1 1 0 1 1
按1和2====》1 0 1 0 1 0 ====》相当于按3
按1和3 ====》0 1 0 1 0 1 ====》相当于按2
按1和4 ====》1 0 0 1 0 0
按2和3 ====》0 0 0 0 0 0 ====》相当于按1
按2和4 ====》1 1 0 0 0 1
按3和4 ====》0 0 1 1 1 0
按1、2、3====》相当于按2遍三 ====》不变
按1、2、4====》相当于按3和4
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int state[9][7]={ {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0},//press 1 {0,0,0,1,1,1,0},//press 3 & 4 {0,0,1,0,1,0,1},//press 2 {0,0,1,1,0,1,1},//press 4 {0,1,0,0,1,0,0},//press 1 & 4 {0,1,0,1,0,1,0},//press 3 {0,1,1,0,0,0,1},//press 2 & 4 {0,1,1,1,1,1,1} //not pressing }; int c,n,x,a[8]; int minn[9]={0,1,2,1,3,2,1,2}; bool flag=0; int main() { freopen("lamps.in","r",stdin); freopen("lamps.out","w",stdout); for(int i=1;i<=6;i++) a[i]=-1; cin>>n>>c; while(cin>>x,x!=-1) { int v=x%6; if(v==0) v=6; a[v]=1; } while(cin>>x,x!=-1) { int v=x%6; if(v==0) v=6; a[v]=0; } for(int i=1;i<=8;i++) { int f=1; for(int j=1;j<=6;j++) { if(a[j]==-1) continue; if(a[j]!=state[i][j]) { f=0; break; } } if(f==1&&(c>=minn[i]||(c==1&&i==4))) { for(int p=1;p<=n;p++) { int v=p%6; if(v==0) v=6; cout<<state[i][v]; flag=1; } cout<<endl; } } if(!flag) cout<<"IMPOSSIBLE"<<endl; return 0; }
以上是关于USACO 2.2 Party Lamps 高能等效+规律枚举的主要内容,如果未能解决你的问题,请参考以下文章
洛谷 P1468 [USACO2.2]派对灯 Party Lamps
[BZOJ] 1631: [Usaco2007 Feb]Cow Party
[USACO07FEB]银牛派对Silver Cow Party