[2016/7/26][usaco 2.2]Party Lamps

来源:互联网 发布:linux svn 编辑:程序博客网 时间:2024/05/19 08:37

这两天因为身体原因没有写题,简直罪过罪过。今天要抓紧时间敲敲敲了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]);elsefor(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;} 


0 0