这两天因为身体原因没有写题,简直罪过罪过。今天要抓紧时间敲敲敲了qwq
http://train.usaco.org/usacoprob2?a=SzjbOuWGTGm&S=lamps
这是一道极其坑的题,调了昨天一下午+今天一早上。
思路倒没什么难的,每六位一个循环,按钮按两下等同于不按。所以最多有2^4种情况,dfs就行了。
关键是!输出要用字典序!!
简直神坑啊。。
又用的bitset,考虑到字典序,所以直接把bitset类型的二进制序列转换为整数,再针对这个排序,最后得出的就是字典序。
但是!!在bitset中,第一位是最右边一位数,如0001,第一位是1。
但是从输出看呢,第一位得是最左边一位数。所以在存储的时候,就要把原有结果逆序存,使它从左到右输出顺序符合题意。最后排序也按逆序的排,毕竟字典序。
中间还有些小细节需要处理,如把灯的标号转换成数组下标。好麻烦orz。
(不知道为什么调着调着就过了系列
代码如下:
/*
ID:49743541
LANG:C++
TASK:lamps
*/
#include <stdio.h>
#include <vector>
#include <bitset>
#include <iostream>
#include <algorithm>
using namespace std;
int N;
int C;
bitset<6> lamp[20];
bitset<6> real[20];
bitset<6> a;
bool flag[20];
int amount = 1;
void operate(int bot){
if(bot==1)
for(int i = 0;i<6;i++)
a[i] = (!a[i]);
else if(bot==2)
for(int i = 0;i<6;i+=2)
a[i] = (!a[i]);
else if(bot==3)
for(int i = 1;i<60;i+=2)
a[i] = (!a[i]);
else
for(int i = 0;i<6;i+=3)
a[i] = (!a[i]);
}
void dfs(int bot,int step){
if(bot>=4) return;
if(step>=C) return;
operate(bot+1);
for(int i = 0;i<6;i++)
lamp[amount][i] = a[5-i];
amount++;
dfs(bot+1,step+1);
operate(bot+1);
dfs(bot+1,step);
}
int trans(int a){
if(a%6==0)
a = 0;
else a = 6-a%6;
return a;
}
bool compare(bitset<6> A,bitset<6> B){
if(A.to_ulong()<B.to_ulong())
return true;
return false;
}
int main(){
// freopen("lamps.in", "r", stdin);
// freopen("lamps.out", "w", stdout);
a = ~a;
lamp[0] = ~lamp[0];
scanf("%d%d",&N,&C);
if(C>4)
C = 4;
int count = 0;
dfs(0,0);
int k;
for(int i = 0;i<amount;i++){
if(!flag[i])
for(int j = 0;j<i;j++){
for(k = 0;k<6;k++){
if(lamp[i][k]!=lamp[j][k]){
break;
}
}
if(k==6){
flag[i] = true;
break;
}
}
}
int on;
scanf("%d",&on);
while(on!=-1){
on = trans(on);
for(int i = 0;i<amount;i++){
if(!flag[i]){
if(lamp[i][on]!=1)
flag[i] = true;
}
}
scanf("%d",&on);
}
int off;
scanf("%d",&off);
while(off!=-1){
off = trans(off);
for(int i = 0;i<amount;i++){
if(!flag[i]){
if(lamp[i][off]!=0)
flag[i] = true;
}
}
scanf("%d",&off);
}
int len = 0;
for(int i = 0;i<amount;i++){
if(!flag[i]){
real[len] = lamp[i];
len++;
}
}
sort(real,real+len,compare);
for(int i = 0;i<len;i++)
cout<<real[i]<<endl;
if(len==0) printf("IMPOSSIBLE\n");
int s = N/6;
int b = N%6;
for(int i = 0;i<len;i++){
for(int j = 0;j<s;j++)
cout<<real[i];
int p = 5;
int x = b;
while(x){
cout<<real[i][p];
p--;
x--;
}
cout<<endl;
}
return 0;
}