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

按1、3、4====》相当于按2和4

再加上不按 ====》1 1 1 1 1 1

共计8种最终状态(红色),故以后所有的状态都是由这8个中的一个为基本循环得到的

完成它们的最少操作次数分别为:1,1,1,3,2,2,2,

就是按4这种情况,按4 可以一步,也可以三步或者三步以上(224)但是就是不能两步达到,故设为3,把按一次的情况特判

二、又由:

按1和按2相当于按3;

按2和按3相当于按1;

按1和按3相当于按2;

按1按2和按3相当于不按;

由(一)和(二)得,c 等于任意操作次数时,我们均可以用(一)搭出规律骨架,用(二)扩充(一)中的操作使凑齐c个操作,以这8个结果为基础,构造答案(只是为了证明正确性,不必输出),最后,只输出最终状态,完毕。

下面为参考代码(借鉴了“ly59782的博客”中的代码):

#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;
}

时间: 2024-10-28 12:49:59

USACO 2.2 Party Lamps 【高能等效+规律枚举】的相关文章

USACO 2.2 Party Lamps 派对灯 (lamps)

题目描述 在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码.这些灯都连接到四个按钮: 按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄灭,本来是关着的灯被点亮. 按钮2:当按下此按钮,将改变所有奇数号的灯. 按钮3:当按下此按钮,将改变所有偶数号的灯. 按钮4:当按下此按钮,将改变所有序号是3*K+1(K>=0)的灯.例如:1,4,7... 一个计数器C记录按钮被按下的次数.当宴会开始,所有的灯都亮着,此时计数器C为0.你将得到计数器C

【USACO 2.2】Preface Numbering (找规律)

求 1-n 的所有罗马数字表达中,出现过的每个字母的个数. 分别对每个数的罗马表达式计算每个字母个数. 对于十进制的每一位,都是一样的规则,只是代表的字母不同. 于是我们从最后一位往前考虑,当前位由字母 s[i] 代表 1,字母 s[i+1] 代表 5,s[i+2] 代表 10(在下一次代表1). 每一位考虑完 i+=2; num[i] 为当前位为i对应的 s[i] 的个数,当前位为 4~8 时,s[i+1] 出现 1 次,当前位为 9 时,s[i+2] 出现一次. http://train.u

USACO Section2.2 Party Lamps 解题报告 【icedream61】

lamps解题报告------------------------------------------------------------------------------------------------------------------------------------------------[题目] N个灯,编号1~N.有4个开关,和C次改变某个开关状态的机会,试问最终所有灯的亮灭情况可能有哪些? 一号开关:改变所有灯的状态. 二号开关:改变所有奇数号灯的状态. 三号开关:改变所有

C# 枚举

一.在学习枚举之前,首先来听听枚举的优点. 1.枚举能够使代码更加清晰,它允许使用描述性的名称表示整数值. 2.枚举使代码更易于维护,有助于确保给变量指定合法的.期望的值. 3.枚举使代码更易输入. 二.枚举说明 1.简单枚举 枚举使用enum关键字来声明,与类同级.枚举本身可以有修饰符,但枚举的成员始终是公共的,不能有访问修饰符.枚举本身的修饰符仅能使用public和internal. 枚举是值类型,隐式继承自System.Enum,不能手动修改.System.Enum本身是引用类型,继承自S

洛谷 P1206 [USACO1.2]回文平方数 Palindromic Squares

题目描述 回文数是指从左向右念和从右向左念都一样的数.如12321就是一个典型的回文数. 给定一个进制B(2<=B<=20,由十进制表示),输出所有的大于等于1小于等于300(十进制下)且它的平方用B进制表示时是回文数的数.用'A','B'--表示10,11等等 输入输出格式 输入格式: 共一行,一个单独的整数B(B用十进制表示). 输出格式: 每行两个B进制的符合要求的数字,第二个数是第一个数的平方,且第二个数是回文数. 输入输出样例 输入样例#1: 10 输出样例#1: 1 1 2 4 3

#415 Div2 Problem C Do you want a data? (math &amp;&amp; 前后缀和 &amp;&amp; 快速幂)

题意: 首先定义集合的F值为  这个集合里面最大值和最小值的差. 现给出一个拥有n个数的集合(没有相同的元素), 要求求出这个集合内所有子集的F的值的和.例如: {4.7}这个集合里面有子集{4}.{7}.{4, 7}, 则这些子集的F值分别为4-4=0.7-7=0.7-4=3, 所以最后的结果就是0+0+3 = 3! 以下分析引用至 : http://blog.csdn.net/dragon60066/article/details/72599167 分析: 不难想到要先使数组升序方便计算和思

枚举类型转换

枚举类型转换成int类型例: 1 public enum Gender 2 { 3 男, 4 女 5 } 6 7 Gender gender = Gender.男; 8 int a = gender; 9 Console.WriteLine(a); 输入结果:0 还有一个功能: 1 public enum Gender 2 { 3 男=5, 4 女 5 } 6 7 Gender gender = Gender.男; 8 int a = gender; 9 Console.WriteLine(a)

第15章 枚举类型和位标志 15.1-15.3

Enumeration提供了一些非常炫酷的功能,相信大多数开发人员都不熟悉.而这些新功能极大的简化了应用程序的开发. 15.1枚举类型 枚举类型(enumerated types)定义了一组“符号名称/值”配对. 以下Color类型定义了一组符号,每个符号都标识一种颜色: internal enum Color { White,//赋值0 Red, //赋值1 Greed,//赋值2 Blue, //赋值3 Orange//赋值4 } 当然,我们也可以写个程序用0代表白色,1代表红色,以此类推.

洛谷 P1458 顺序的分数 Ordered Fractions

P1458 顺序的分数 Ordered Fractions 题目描述 输入一个自然数N,对于一个最简分数a/b(分子和分母互质的分数),满足1<=b<=N,0<=a/b<=1,请找出所有满足条件的分数. 这有一个例子,当N=5时,所有解为: 0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1 给定一个自然数N,1<=n<=160,请编程按分数值递增的顺序输出所有解. 注:①0和任意自然数的最大公约数就是那个自然数②互质指最大公约数等于