usaco Party Lamps report

来源:互联网 发布:java excel 下拉联动 编辑:程序博客网 时间:2024/05/17 01:31

这道题核心的算法是搜索,然后用状态压缩(位运算)来优化。

有必要好好体会一下位运算具体的实施过程,把一些看起来不太容易用位运算做的问题使用其来提速。

换句话讲,每一个步骤都考虑到其最优的可能对于整体性能的提升是很重要的。

首先1《《a,可以表示一个在第a位置上是1的数,如果现在用一个状态数b,b&a用来检测b的第a位置上是否为1.

|的作用往往体现在添加状态,b|a可以使第a位变成1,无论之前是什么。

还要记住一个^异或运算符,自己造好需要的运算。检测一下它的可行性就好。

标准答案写的比我的精简多了,所以我就不贴自己的了,直接附上标程以供参考:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#define MAXLAMP6#define LAMPMASK((1<<MAXLAMP)-1)int nlamp;int nswitch;int ison;int known;int poss[1<<MAXLAMP];int flip[4] = {    LAMPMASK,/* flip all lights */    LAMPMASK & 0xAA, /* flip odd lights */    LAMPMASK & 0x55,/* flip even lights */    LAMPMASK & ((1<<(MAXLAMP-1))|(1<<(MAXLAMP-4)))/* lights 1, 4 */};/* * Starting with current light state ``lights'', flip exactly n switches * with number >= i. */voidsearch(int lights, int i, int n){    if(n == 0) {if((lights & known) == ison)    poss[lights] = 1;return;    }    for(; i<4; i++)search(lights ^ flip[i], i+1, n-1);}voidprintseq(FILE *fout, int lights){    int i;    char s[100+1];    for(i=0; i<nlamp; i++)s[i] = (lights & (1<<(MAXLAMP-1 - i%MAXLAMP))) ? '1' : '0';    s[nlamp] = '\0';    fprintf(fout, "%s\n", s);}voidmain(void){    FILE *fin, *fout;    int a, i, impossible;    fin = fopen("lamps.in", "r");    fout = fopen("lamps.out", "w");    assert(fin != NULL && fout != NULL);    fscanf(fin, "%d %d", &nlamp, &nswitch);    for(;;) {fscanf(fin, "%d", &a);if(a == -1)    break;a = MAXLAMP-1 - (a-1) % MAXLAMP;ison |= 1<<a;known |= 1<<a;    }    for(;;) {fscanf(fin, "%d", &a);if(a == -1)    break;a = MAXLAMP-1 - (a-1) % MAXLAMP;assert((ison & (1<<a)) == 0);known |= 1<<a;    }    if(nswitch > 4)if(nswitch%2 == 0)    nswitch = 4;else    nswitch = 3;    for(; nswitch >= 0; nswitch -= 2)    search(LAMPMASK, 0, nswitch);    impossible = 1;    for(i=0; i<(1<<MAXLAMP); i++) {if(poss[i]) {    printseq(fout, i);    impossible = 0;}    }    if(impossible)fprintf(fout, "IMPOSSIBLE\n");    exit(0);}


0 0
原创粉丝点击