USACO lamps

IOI 98称号。然后,它似乎没有很困难。即使我能做到这一点微弱的残留物。所有的button按两次不按,高达因此实际上总的等效按4二级,首先C往下<=4,则搜索将能直接照射,总共只有16状态(事实上,没有),需要注意的是重判和订购,我们会处理的话非常快的二进制。= =不幸的是,我不会,转字符串。假设数据大点直接就挂了= =

/*
ID:kevin_s1
PROG:lamps
LANG:C++
*/

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <list>
#include <cmath>
#include <bitset>
#include <strstream>

using namespace std;

//gobal variable====
int N;
int C;
int state[101];
int on, off;
int ons[101], offs[101];
int _count;
vector<long long> hash;
vector<string> result;
//==================

//function==========
void print(){
	for(int i = 1; i <= N; i++){
		cout<<state[i];
	}
	cout<<endl;
}

void init(){
	for(int i = 1; i <= N; i++)
		state[i] = 1;
}

bool check(){
	for(int i = 0; i < on; i++){
		if(state[ons[i]] != 1){
			return false;
		}
	}
	for(int i = 0; i < off; i++){
		if(state[offs[i]] != 0){
			return false;
		}
	}
	return true;
}

void change(int i){
	if(state[i] == 0)
		state[i] = 1;
	else if(state[i] == 1)
		state[i] = 0;
}

void Button1(){
	for(int i = 1; i <= N; i++){
		change(i);
	}
}

void Button2(){
	for(int i = 1; i <= N; i+=2){
		change(i);
	}
}

void Button3(){
	for(int i = 2; i <= N; i+=2){
		change(i);
	}
}

void Button4(){
	for(int i = 0; (3*i + 1) <= N; i++){
		int k = 3 * i + 1;
		change(k);
	}
}

void Button(int i){
	if(i == 1)
		Button1();
	if(i == 2)
		Button2();
	if(i == 3)
		Button3();
	if(i == 4)
		Button4();
}

void DFS(int i){
	if(i > C)
		return;
	if(check()){
		long long sum = 0;
		for(int i = 1; i <= N; i++){
			sum = sum * 10;
			sum = sum + state[i];
		}
		vector<long long>::iterator iter = find(hash.begin(), hash.end(), sum);
		if(iter == hash.end()){
			_count++;
			hash.push_back(sum);
			string str;
			for(int i = 1; i <= N; i++){
				char ch = state[i] + 48;
				str = str + ch;
			}
			result.push_back(str);
		}
	}
	for(int j = 1; j <= 4; j++){
		Button(j);
		DFS(i + 1);
		Button(j);
	}
	return;
}

//==================

int main(){
	freopen("lamps.in","r",stdin);
	freopen("lamps.out","w",stdout);
	cin>>N;
	cin>>C;
	on = 0, off = 0;
	_count = 0;
	int _on, _off;
	while(cin>>_on && _on != -1){
		ons[on++] = _on;
	}
	while(cin>>_off && _off != -1){
		offs[off++] = _off;
	}
	init();
	while(C > 4){
		C = C - 2;
	}
	DFS(0);
	sort(result.begin(), result.end(), less<string>());
	vector<string>::iterator iter = result.begin();
	for(;iter != result.end(); iter++){
		cout<<*iter<<endl;
	}
	if(_count == 0){
		cout<<"IMPOSSIBLE"<<endl;
	}
	return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-08-24 06:05:34

USACO lamps的相关文章

usaco Party Lamps

题意很简单,可以看翻译http://www.wzoi.org/usaco/13%5C104.asp 因为同一个开关按两次的等于没按,所以当C大于4时,可以将C一直减2,减到小于等于4为止,然后开始枚举,分析题目之后发现可以用一个6位二进制表示前6个等,后面的等每6个和前面的一样 0和1异或上0不变,异或上1之后0变1,1变0 给当前状态异或上不同的二进制就是按了开关之后的状态. DFS就能解 /* ID: modengd1 PROG: lamps LANG: C++ */ #include <i

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 Section 2.2 Party Lamps

/* ID: lucien23 PROG: lamps LANG: C++ */ /* * 此题的技巧之处就是需要注意到任何button只要按下2的倍数次就相当于没有按 * 所以其实只需要考虑4个按钮,每个按钮是否被有效按下过一次就好 * 直接使用枚举法,一共只有2^4=16种情况 * 对于每种情况需要知道被按下的有效次数(也就是被按下过的按钮数),必须满足 * (C-有效次数)%2=0才行,这样其他次数才能视为无效 * 然后验证各种情况是否符合要求,将符合要求的情况按序输出即可 */ #inc

USACO Party Lamps 【Binary code solvution】【规律】

写这道题目的时候遇到了一个令人诧异的问题,就是平台上跑来的结果和我本机跑起来的结果不一样. 后来Debug了之后才发现是我数组开小了,只开到100 的数组竟然都去访问他170位的地址肯定要跪成翔啊... 好吧,解释一下题意. 有N盏台灯,C次操作 每次操作可以按一次按钮,一共一个四个按钮 可以得出的规律是每6个台灯是一次循环. 易得证.(其实不难发现Button 1 不用考虑,Button 2 和 Button 3 对立, 那么Button 4 的作用就是让1, 4, 7, 11改变状态 那么可

【USACO 2.2】Party Lamps

四种开关,n盏灯,1:改变所有灯状态,2:改变奇数灯状态,3:改变偶数灯状态,4:改变3k+1灯状态 给你按开关的总次数c和部分灯限制条件(开或关),一开始都是开着的.($c \leq 10000,n \leq 100$) 我直接考虑每个开关按了奇数次或偶数次,因为顺序和总次数不影响结果,重要的是每种开关按的次数是奇数还是偶数次. 题解里有个flip[i]= (1<<6-1)&0x55 和与上0xAA,分别代表2.3开关,因为0x55就是01010101,0xAA就是10101010,

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

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

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个灯为一

【USACO 2.2.4】派对灯

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

COGS 696. [IOI1996][USACO 2.3] 最长前缀

★   输入文件:prefix.in   输出文件:prefix.out   简单对比时间限制:1 s   内存限制:128 MB 描述 USACO 2.3.1 IOI96 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素.元素不一定要全部出现(如下例中B