题解

83 条题解

  • 4
    @ 2017-05-08 12:40:21
    /*
    一道很经典的bfs了吧~
    dfs也可以做但是bfs更优一些~
    我们看到这个题目是对于多个状态计算六步之内能否到达全1状态
    n可以达到500
    那么我们如果对于读入的五百个数据
    每次都bfs找到全1的最短路
    这样其实是肯定会有很多重复计算的
    这样效率必然很低!
    那么我们可以逆向思维
    和P1029一样的利用离线查找
    从全1状态开始逆推6步
    再将这些状态全部储存下来~
    这样就可以对于读入的500个数据直接查表出解~
    效率高了很多s
    位运算的一些细节就不多说了
    关键是反转的change函数要注意一些细节了~
    还是很简单的~
    */
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    const int MAXN=33554435;
    int ans[MAXN];
    int n;
    int s,t=(1<<25)-1;
    
    void work()
    {
        string a;
        s=0;
        for(int i=0;i<5;i++)
        {
            cin>>a;
            for(int j=0;j<5;j++)
                if(a[j]=='1')
                    s|=(1<<(i*5+j));
        }
        cout<<ans[s]<<endl;
    }
    
    int change(int x,int p)
    {
        x^=(1<<p);
        if(p>=5)        x^=(1<<(p-5));
        if(p<20)    x^=(1<<(p+5));
        if(p%5)     x^=(1<<(p-1));
        if(p%5!=4)  x^=(1<<(p+1));
        return x;
    }
    
    void bfs()
    {
        memset(ans,-1,sizeof(ans));
        queue<int> q;
        q.push(t);  ans[t]=0;
        int p;
        while(!q.empty())
        {
            int u=q.front();    q.pop();
            if(ans[u]>=6)
                return;
            for(int i=0;i<25;i++)
            {
                p=change(u,i);
                if(ans[p]==-1)
                {
                    q.push(p);
                    ans[p]=ans[u]+1;
                }
            }
        }
        return;
    }
    
    int main()
    {
        scanf("%d",&n);
        bfs();
        while(n--)
            work();
    }
         
    
  • 1
    @ 2020-11-10 22:34:07
    //从《算法竞赛进阶指南》过来的
    //枚举第一行,并采用lowbit对点击进行处理
    #include <iostream>
    #include <algorithm>
    #include <bitset>
    using namespace std;
    int a[5], b[5];
    
    void myscanf()
    {
        bitset<5> bint;  // 16 bit 二进制数据,还有 bitset<32>
        for (int i = 0; i < 5; i++)
        {
            cin >> bint;
            b[i] = bint.to_ulong();
        }
    }
    
    void click(int row, int k)
    {
        a[row] ^= 1 << k;
        if (k - 1 >= 0) a[row] ^= 1 << (k - 1);
        if (k + 1 <= 4) a[row] ^= 1 << (k + 1);
        if (row - 1 >= 0) a[row - 1] ^= 1 << k;
        if (row + 1 <= 4) a[row + 1] ^= 1 << k;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie();
        int n;
        cin >> n;
        int h[40];
        for (int k = 0; k < 5; k++) h[1 << k] = k;
    
        for (int i = 0; i < n; i++)
        {
            myscanf();
            int result = 9999999;
            for (int m = 0; m < 32; m ++)
            {
                for (int j = 0; j < 5; j++) a[j] = b[j];
                int count = 0;
                int temp = m;
                while (temp)
                {
                    click(0, h[temp & -temp]);
                    count++;
                    temp = temp - (temp & -temp);
                }
                
                for (int j = 0; j < 4; j++)
                {
                    temp = (1 << 5) - a[j] - 1;
                    while (temp)
                    {
                        click(j + 1, h[temp & -temp]);
                        count++;
                        temp = temp - (temp & -temp);
                    }
                }
                if (a[4] == 31) result = result < count ? result : count;
            }       
            result <= 6 ? printf("%d\n", result) : printf("%d\n", -1);
        }
        return 0;
    }
    
  • 1
    @ 2018-03-22 16:02:53

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int t;
    int ans[(1<<25)],q[(1<<20)];
    char ch;
    int change(int x,int k)
    {
    x^=(1<<k);
    if(k>4) x^=(1<<(k-5));
    if(k<20) x^=(1<<(k+5));
    if(k%5) x^=(1<<(k-1));
    if(k%5<4) x^=(1<<(k+1));
    return x;
    }
    void bfs()
    {
    memset(ans,-1,sizeof(ans));
    q[1]=(1<<25)-1; ans[(1<<25)-1]=0;
    int l=0,r=1;
    while(l<r)
    {
    int u=q[++l];
    if(ans[u]==6) return ;
    for(int i=0;i<25;i++)
    {
    int v=change(u,i);
    if(ans[v]<0) q[++r]=v,ans[v]=ans[u]+1;
    }
    }
    }
    int main()
    {
    scanf("%d",&t);
    bfs();
    while(t--)
    {
    int x=0;
    for(int i=0;i<5;i++)
    for(int j=0;j<5;j++)
    {
    x<<=1;
    cin>>ch;
    x+=ch-'0';
    }
    cout<<ans[x]<<endl;
    }
    return 0;
    }

  • 1
    @ 2016-05-25 22:56:34

    位运算+BFS
    c++
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    using namespace std;
    struct qj{int f,t;};
    qj qjj(int a,int b){qj tmp;tmp.f=a,tmp.t=b;return tmp;}
    qj ld[6]={qjj(1,5),qjj(6,10),qjj(11,15),qjj(16,20),qjj(21,25)};
    struct node{int sta,dep; node(int sta,int dep) : sta(sta),dep(dep){}};
    const int org=(1<<25)-1;
    const int hashsize=5000;
    queue<node> que;
    vector<node> hash[hashsize+1];
    int chang(int T,int mov){
    int w=0;
    int f=1,f1=2,f2=3;
    w=T ^ (1 << mov-1);
    for(int i=0;i<=4;i++)
    if(mov>=ld[i].f && mov<=ld[i].t) {f=i; break;}
    for(int i=0;i<=4;i++)
    if(mov+1>=ld[i].f && mov+1<=ld[i].t) {f1=i; break;}
    for(int i=0;i<=4;i++)
    if(mov-1>=ld[i].f && mov-1<=ld[i].t) {f2=i; break;}
    if(f1==f) w=w ^ (1 << (mov+1)-1);
    if(f2==f) w=w ^ (1 << (mov-1)-1);
    //左右和中间
    if(mov+5 <= 25) w=w ^ (1 << (mov+5)-1);
    if(mov-5 > 0) w=w ^ (1 << (mov-5)-1);
    return w;
    }
    int finhash(int T){
    int a=T%hashsize;
    for(int i=0;i<hash[a].size();i++)
    if(hash[a][i].sta==T)
    return i;
    return -1;
    }
    int addhash(int T,int dep){
    int a=T%hashsize,b=finhash(T);
    if(b==-1)
    hash[a].push_back(node(T,dep));
    else{
    if(hash[a][b].dep>dep) hash[a][b]=node(T,dep);
    else return -1;
    }
    return 1;
    }
    int bfs(int T,int dep){
    que.push(node(T,dep));
    addhash(org,0);
    while(!que.empty()){
    node tmp=que.front(); que.pop();
    for(int i=1;i<=25;i++){
    node nw=node(chang(tmp.sta,i),tmp.dep+1);
    if(nw.dep<=6 && addhash(nw.sta,nw.dep)==1){
    que.push(nw);
    //cout<<nw.sta<<" "<<finhash(nw.sta)<<endl;
    }
    }
    }
    return 0;
    }
    int main(){
    int n,tmp2n,a,b;
    char tmp[6],tmp2[26];
    bfs(org,0);
    scanf("%d",&n);
    for(int kk=0;kk<n;kk++){
    tmp2n=0;
    for(int i=0;i<5;i++){scanf("%s",&tmp); for(int j=0;j<5;j++) tmp2[tmp2n++]=tmp[j];}
    int base=1,sum=0,ans;
    for(int i=24;i>=0;i--){sum+=(tmp2[i]-'0')*base; base*=2;}
    ans=finhash(sum);
    if(ans != -1)
    printf("%d\n",hash[sum%hashsize][ans].dep);
    else printf("-1\n");
    }
    return 0;
    }

  • 0
    @ 2019-04-03 11:20:12

    纯dfs

    #include <bits/stdc++.h>
    using namespace std;
    int re=99999999,num[10][10],ans,f;
    string st[10];
    vector<int> v;
    void sum()
    {
      for(int i=2;i<=5;i++)
      for(int j=1;j<=5;j++)
      if(num[i-1][j]==0)
      {
        ans++;
        num[i][j-1]=!num[i][j-1];
        num[i][j+1]=!num[i][j+1];
        num[i][j]=!num[i][j];
        num[i+1][j]=!num[i+1][j];
        num[i-1][j]=!num[i-1][j];
      }
      for(int i=1;i<=5;i++)
      for(int j=1;j<=5;j++)
      if(num[i][j]==0)
      {
        f=1;
        break;
      }
    }
    void dfs(int x)
    {
      if(x==6)
      {
        f=0;
        ans=0;
        for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
        num[i][j]=st[i][j]-'0';
        for(int i=1;i<v.size();i++)
        {
          //cout<<v[i]<<" ";
          if(v[i])
          {
            num[1][i-1]=!num[1][i-1];
            num[1][i+1]=!num[1][i+1];
            num[1][i]=!num[1][i];
            num[2][i]=!num[2][i];
            ans++;
          }
        }
        /*cout<<"\n\n";
        for(int i=1;i<=5;i++)
        {
          for(int j=1;j<=5;j++)
          cout<<num[i][j]<<" ";
          cout<<"\n";
        }
        cout<<"\n";*/
        sum();
        if(!f)
        re=min(re,ans);
        return;
      }
      v.push_back(0);
      dfs(x+1);
      v.pop_back();
      v.push_back(1);
      dfs(x+1);
      v.pop_back();
    }
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n;
      cin>>n;
      while(n--)
      {
        v.clear();
        v.push_back(3);
        re=99999999;
        for(int i=1;i<=5;i++)
        {
          cin>>st[i];
          st[i].insert(0,"0");
        }
        for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
        num[i][j]=st[i][j]-'0';
        dfs(1);
        if(re<=6)
        cout<<re<<"\n";
        else
        cout<<-1<<"\n";
      }
    }
    
  • 0
    @ 2019-03-16 22:37:05

    代码来源:李煜东《算法竞赛进阶指南(第三版)》

    // Author: LiRe
    #include <iostream>
    #include <cstdio>
    using namespace std;
    #define INF 0x3fffff
    char k[5][5]; int a[5][5];
    int vx[5] = {-1, 0, 1, 0, 0}, vy[5] = {0, 1, 0, -1, 0};
    inline void click(int c, int t) {
        for(int i = 0; i < 5; ++i)
            if(c + vx[i] >= 0 && t + vy[i] >= 0 && c + vx[i] < 5 && t + vy[i] < 5){
                a[c + vx[i]][t + vy[i]] ^= 1;
            }
    
    }
    int main() {
        int T; 
        scanf("%d", &T);
        while(T--) {
            for(int i = 0; i < 5; ++i)
                for(int j = 0; j < 5; ++j)
                    cin>>k[i][j];
            for(int i = 0; i < 5; ++i)
                for(int j = 0; j < 5; ++j)
                    a[i][j] = (int)(k[i][j] - '0');
            int ans = INF, cnt = 0, flag = 0;
            for(int i = 0; i < 32; ++i) {
                flag = 0; cnt = 0;
                for(int j = 0; j < 5; ++j)
                    if((i >> j) & 1) ++cnt, click(0, j);
                for(int j = 0; j < 4; ++j) {
                    for(int k = 0; k < 5; ++k) {
                        if(!a[j][k]) ++cnt, click(j + 1, k);
                    }
    
                }
                for(int i = 0; i < 5; ++i)
                    for(int j = 0; j < 5; ++j)
                        if(!a[i][j]) {flag = 1; break;}
                if(!flag) ans = min(ans, cnt);
                for(int i = 0; i < 5; ++i)
                    for(int j = 0; j < 5; ++j)
                        a[i][j] = k[i][j] - '0';
            }
            if(ans == INF || ans > 6) printf("%d\n", -1);
            else printf("%d\n", ans);
        }
    
    }
    
  • 0
    @ 2018-12-15 16:50:23

    #include<bits/stdc++.h>
    using namespace std;

    char s[10];
    int f[10][10],g[10][10];

    void change(int x,int y){
    f[x][y]^=1; f[x+1][y]^=1; f[x-1][y]^=1;
    f[x][y+1]^=1; f[x][y-1]^=1;
    }

    int main(){
    int T;
    scanf("%d",&T);
    while (T--){
    for (int i=1;i<=5;i++){
    scanf("%s",s+1);
    for (int j=1;j<=5;j++)
    g[i][j]=s[j]-'0';
    }
    int ans=10000;
    for (int mask=0;mask<=(1<<5);mask++){
    for (int i=1;i<=5;i++)
    for (int j=1;j<=5;j++) f[i][j]=g[i][j];
    int cnt=0,s=mask;
    for (int x=1;x<=5;x++){
    for (int i=0;i<5;i++) if ((s>>i)&1){
    cnt++;change(x,5-i);
    }
    s=0;
    for (int i=1;i<=5;i++) if (f[x][i]==0) s|=1<<(5-i);
    }if (s==0) ans=min(ans,cnt);
    }
    if (ans>6) ans=-1;
    printf("%d\n",ans);
    }
    return 0;
    }

  • 0
    @ 2018-06-23 15:12:56

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int mp[6][6],temp[6][6];
    int h[6],sum=9999999;
    char st[10];
    char read()
    {
    char c=getchar();
    while(c==' '||c=='\n')
    c=getchar();
    return c;
    }
    int work()
    {
    int ans=0;
    for(int i=1;i<=5;i++)
    if(h[i]) ans++;
    for(int i=1;i<=5;i++)
    {
    if(h[i])
    {
    temp[1][i]^=h[i];
    temp[2][i]^=h[i];
    temp[1][i+1]^=h[i];
    temp[1][i-1]^=h[i];
    }
    }
    for(int i=2;i<=5;i++)
    {
    for(int j=1;j<=5;j++)
    {
    if(!temp[i-1][j])
    {
    temp[i][j]^=1;
    temp[i][j-1]^=1;
    temp[i][j+1]^=1;
    temp[i+1][j]^=1;
    temp[i-1][j]^=1;
    ans++;
    }
    }
    }
    for(int i=1;i<=5;i++)
    for(int j=1;j<=5;j++)
    if(!temp[i][j])
    return -1;
    return ans;
    }
    void run(int cur,int cnt)
    {
    if(cur>cnt)
    {
    //tryit();
    //move();
    // for(int i=1;i<=5;i++)
    // printf("%d",h[i]);
    int d=work();
    if(d!=-1)
    sum=min(sum,d);
    for(int i=1;i<=5;i++)
    for(int j=1;j<=5;j++)
    temp[i][j]=mp[i][j];
    return ;
    }
    for(int i=0;i<=1;i++)
    {
    h[cur] = i ;
    run(cur+1,cnt);
    }
    }
    int main()
    {
    int T;
    cin>>T;
    while(T--)
    {
    for(int i=1;i<=5;i++)
    for(int j=1;j<=5;j++)
    {
    mp[i][j]=read()-48;
    temp[i][j]=mp[i][j];
    }
    run(1,5);
    if(sum>6)
    printf("-1\n");
    else
    printf("%d\n",sum);
    sum=9999999;
    }
    }
    /*
    0 0 1 1 1
    0 1 0 1 1
    1 0 0 0 1
    1 1 0 1 0
    1 1 1 0 0*/
    第一行全排列 + 暴力求解

  • 0
    @ 2017-07-16 17:17:28

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;

    bool b[7][7]={0},c[5];

    int meiju(int cnt){
    bool a[7][7]={0};
    for(int i=1;i<=5;i++)
    for(int j=1;j<=5;j++)
    a[i][j]=b[i][j];
    for(int i=0;i<5;i++){
    if(c[i]){
    a[1][i+1]=!a[1][i+1];
    a[1][i+2]=!a[1][i+2];
    a[1][i]=!a[1][i];
    a[2][i+1]=!a[2][i+1];
    }
    }
    for(int i=2;i<=5;i++){
    for(int j=1;j<=5;j++){
    if(!a[i-1][j]){
    a[i][j+1]=!a[i][j+1];
    a[i][j-1]=!a[i][j-1];
    a[i-1][j]=!a[i-1][j];
    a[i+1][j]=!a[i+1][j];
    a[i][j]=!a[i][j];
    cnt++;
    if(cnt>6)return -1;
    }
    }
    }
    for(int j=1;j<=5;j++){
    if(!a[5][j])return -1;
    }
    return cnt;
    }
    int main()
    {
    int n,cnt=1<<30,s;
    scanf("%d",&n);
    for(int k=0;k<n;k++){
    cnt=1<<30;
    for(int i=1;i<=5;i++){
    string ss;
    cin>>ss;
    for(int j=0;j<5;j++){
    b[i][j+1]=(ss[j]-'0');
    }
    }
    for(int i1=0;i1<=1;i1++){
    c[0]=i1;
    for(int i2=0;i2<=1;i2++){
    c[1]=i2;
    for(int i3=0;i3<=1;i3++){
    c[2]=i3;
    for(int i4=0;i4<=1;i4++){
    c[3]=i4;
    for(int i5=0;i5<=1;i5++){
    c[4]=i5;
    s=meiju(i1+i2+i3+i4+i5);
    if(s!=-1)cnt=min(cnt,s);
    }
    }
    }
    }
    }
    if(cnt>6)printf("-1\n");
    else printf("%d\n",cnt);
    }
    }
    我是oier

  • 0
    @ 2016-10-30 19:23:39

    离线查找,每个点时间都在200ms左右了

  • 0
    @ 2016-10-30 18:49:05
    位运算好题!
    把灯化为二进制保存,从终点BFS搜索6步内能到达的方案,读入输出就行(具体见程序,你应该看得懂)。
    就是时间并不快。
    //{$define files}
    var n,i,j,p,t:longint;
    c:char;
    l:shortint;
    q:array[1..200000,1..2]of longint;
    ans:array[0..1 shl 25]of longint;
    procedure bfs;
    var l,r,d,i,t:longint;
    begin
     l:=0;
     r:=1;
     q[1,1]:=0;
     q[1,2]:=1<<25-1;
     while(l<>r)do
     begin
      l:=l mod 199999+1;
      d:=q[l,2];
      if q[l,1]>=6 then break;
      for i:=0 to 24 do
      begin
       t:=d;
       if i mod 5<>0 then
       t:=t xor(1 shl(i-1));
       if i mod 5<>4 then
       t:=t xor(1 shl(i+1));
       if i div 5<>0 then
       t:=t xor(1 shl(i-5));
       if i div 5<>4 then
       t:=t xor(1 shl(i+5));
       t:=t xor(1 shl i);
       if(ans[t]=-1)then
       begin
        ans[t]:=q[l,1]+1;
        r:=r mod 199999+1;
        q[r,1]:=ans[t];
        q[r,2]:=t;
       end;
      end;
     end;
    end;
    begin
     {$ifdef files}
     assign(input,'in.txt');reset(input);
     assign(output,'out.txt');rewrite(output);
     {$endif}
     fillchar(ans,sizeof(ans),255);
     ans[1<<25-1]:=0;
     bfs;
     readln(n);
     for p:=1 to n do
     begin
      t:=0;
      for i:=1 to 5 do
      begin
       for j:=1 to 5 do
       begin
        read(c);
        l:=ord(c)-ord('0');
        t:=t shl 1 or l;
       end;
       readln;
      end;
      readln;
      writeln(ans[t]);
     end;
     {$ifdef files}
     close(input);close(output);
     {$endif}
    end.
    
    
  • 0
    @ 2016-05-25 22:55:52

    位运算的乱入
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    using namespace std;
    struct qj{int f,t;};
    qj qjj(int a,int b){qj tmp;tmp.f=a,tmp.t=b;return tmp;}
    qj ld[6]={qjj(1,5),qjj(6,10),qjj(11,15),qjj(16,20),qjj(21,25)};
    struct node{int sta,dep; node(int sta,int dep) : sta(sta),dep(dep){}};
    const int org=(1<<25)-1;
    const int hashsize=5000;
    queue<node> que;
    vector<node> hash[hashsize+1];
    int chang(int T,int mov){
    int w=0;
    int f=1,f1=2,f2=3;
    w=T ^ (1 << mov-1);
    for(int i=0;i<=4;i++)
    if(mov>=ld[i].f && mov<=ld[i].t) {f=i; break;}
    for(int i=0;i<=4;i++)
    if(mov+1>=ld[i].f && mov+1<=ld[i].t) {f1=i; break;}
    for(int i=0;i<=4;i++)
    if(mov-1>=ld[i].f && mov-1<=ld[i].t) {f2=i; break;}
    if(f1==f) w=w ^ (1 << (mov+1)-1);
    if(f2==f) w=w ^ (1 << (mov-1)-1);
    //左右和中间
    if(mov+5 <= 25) w=w ^ (1 << (mov+5)-1);
    if(mov-5 > 0) w=w ^ (1 << (mov-5)-1);
    return w;
    }
    int finhash(int T){
    int a=T%hashsize;
    for(int i=0;i<hash[a].size();i++)
    if(hash[a][i].sta==T)
    return i;
    return -1;
    }
    int addhash(int T,int dep){
    int a=T%hashsize,b=finhash(T);
    if(b==-1)
    hash[a].push_back(node(T,dep));
    else{
    if(hash[a][b].dep>dep) hash[a][b]=node(T,dep);
    else return -1;
    }
    return 1;
    }
    int bfs(int T,int dep){
    que.push(node(T,dep));
    addhash(org,0);
    while(!que.empty()){
    node tmp=que.front(); que.pop();
    for(int i=1;i<=25;i++){
    node nw=node(chang(tmp.sta,i),tmp.dep+1);
    if(nw.dep<7 && addhash(nw.sta,nw.dep)==1){
    que.push(nw);
    //cout<<nw.sta<<" "<<finhash(nw.sta)<<endl;
    }
    }
    }
    return 0;
    }
    int main(){
    int n,tmp2n,a,b;
    char tmp[6],tmp2[26];
    bfs(org,0);
    scanf("%d",&n);
    for(int kk=0;kk<n;kk++){
    tmp2n=0;
    for(int i=0;i<5;i++){scanf("%s",&tmp); for(int j=0;j<5;j++) tmp2[tmp2n++]=tmp[j];}
    int base=1,sum=0,ans;
    for(int i=24;i>=0;i--){sum+=(tmp2[i]-'0')*base; base*=2;}
    ans=finhash(sum);
    if(ans != -1)
    printf("%d\n",hash[sum%hashsize][ans].dep);
    else printf("-1\n");
    }
    return 0;
    }

  • 0
    @ 2016-03-22 07:31:55

    好恶心的时间QWQ
    编译成功

    测试数据 #0: Accepted, time = 250 ms, mem = 263208 KiB, score = 10

    测试数据 #1: Accepted, time = 265 ms, mem = 263204 KiB, score = 10

    测试数据 #2: Accepted, time = 281 ms, mem = 263208 KiB, score = 10

    测试数据 #3: Accepted, time = 203 ms, mem = 263208 KiB, score = 10

    测试数据 #4: Accepted, time = 265 ms, mem = 263204 KiB, score = 10

    测试数据 #5: Accepted, time = 265 ms, mem = 263204 KiB, score = 10

    测试数据 #6: Accepted, time = 265 ms, mem = 263204 KiB, score = 10

    测试数据 #7: Accepted, time = 281 ms, mem = 263208 KiB, score = 10

    测试数据 #8: Accepted, time = 250 ms, mem = 263204 KiB, score = 10

    测试数据 #9: Accepted, time = 250 ms, mem = 263204 KiB, score = 10

    Accepted, time = 2575 ms, mem = 263208 KiB, score = 100

  • 0
    @ 2015-10-27 13:05:32

    #include <stdio.h>
    #include <stdlib.h>

    #define STATUS 0
    #define STEP 1

    int queue[1000000][2];
    int answer[1<<25];
    int head = 0, tail = 0;

    void addToQueue(int status, int step){
    queue[tail][STATUS] = status;
    queue[tail][STEP] = step;
    answer[status] = step;
    tail++;
    }
    int main(){
    char line[10];
    int numQuery, i, j, k, step, status;

    for(i=0; i<(1<<25); i++)
    answer[i] = -1;

    addToQueue((1<<25)-1, 0); //all lights up
    while(head < tail){
    status = queue[head][STATUS];
    step = queue[head][STEP];
    if(step < 6){
    for(i=0; i<25; i++){
    k = status;

    // generate new status
    k ^= 1<<i; //itself
    if(i%5 != 0)
    k ^= 1<<(i-1); //left
    if(i%5 != 4)
    k ^= 1<<(i+1); //right
    if(i/5 != 0)
    k ^= 1<<(i-5); //up
    if(i/5 != 4)
    k ^= 1<<(i+5); //down

    if(answer[k] == -1)
    addToQueue(k, step+1);
    }
    }
    head++;
    }

    scanf("%d", &numQuery);
    for(i=0; i<numQuery; i++){
    status = 0;
    for(j=0; j<5; j++){
    scanf("%s", line);
    for(k=0; k<5; k++){
    status <<= 1;
    status |= line[k]-'0';
    }
    }
    printf("%d\n", answer[status]);
    }
    return 0;
    }

    BFS + 状态压缩,从全亮的状态开始往回推6步。answer[status]表示状态为 status 的操作数

  • 0
    @ 2009-11-11 19:40:07

    位运算ko了

  • 0
    @ 2009-11-10 16:43:03

    打了50行头越来越晕了I.I

    位运算这东西还是以后再玩吧。

  • 0
    @ 2009-10-31 15:45:16

    大家注意:一定要开byte,否则会MLE的!!!

    第一次

    编译通过...

    ├ 测试数据 01:内存溢出...

    ├ 测试数据 02:内存溢出...

    ├ 测试数据 03:内存溢出...

    ├ 测试数据 04:内存溢出...

    ├ 测试数据 05:内存溢出...

    ├ 测试数据 06:内存溢出...

    ├ 测试数据 07:内存溢出...

    ├ 测试数据 08:内存溢出...

    ├ 测试数据 09:内存溢出...

    ├ 测试数据 10:内存溢出...

    ---|---|---|---|---|---|---|---|-

    Unaccepted 有效得分:0 有效耗时:0ms

    第二次

    编译通过...

    ├ 测试数据 01:答案正确... 88ms

    ├ 测试数据 02:答案正确... 72ms

    ├ 测试数据 03:答案正确... 72ms

    ├ 测试数据 04:答案正确... 103ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 88ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 88ms

    ├ 测试数据 09:答案正确... 103ms

    ├ 测试数据 10:答案正确... 0ms

  • 0
    @ 2009-10-10 19:49:17

    超级强大的位运算;广搜不能求出任意步数的状态的最小步数;我的程序能!!!!!

    program er;

    var a:array[0..30] of longint;

    i,j,o,n,ans,k,now,old,te,u,ji:longint;

    ch:char;

    procedure init;

    begin

    fillchar(a,sizeof(a),0);

    for i:=1 to 5 do begin

    for j:=1 to 5 do begin

    read(ch);

    if ch='0' then a[i]:=a[i]+1 shl (j-1);

    end;

    readln;

    end;

    end;

    begin

    readln(n);

    k:=1 shl 5-1;

    for o:=1 to n do

    begin

    init;

    ans:=maxlongint;

    for i:=0 to k do

    begin

    now:=i;

    old:=0;

    ji:=0;

    for j:=1 to 5 do

    begin

    te:=now;

    now:=(now xor (now shr 1) xor (now shl 1) xor a[j] xor old)and k;

    old:=te;

    for u:=1 to 5 do

    if te and (1 shl (u-1))=(1 shl (u-1)) then inc(ji);

    end;

    if (now=0)and(ji

  • 0
    @ 2009-09-30 18:16:54

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    哈哈

  • 0
    @ 2009-09-25 12:05:20

    写了朴素广搜,利用二进制判重,结果…………全超时: -(

信息

ID
1197
难度
6
分类
搜索 点击显示
标签
(无)
递交数
1684
已通过
508
通过率
30%
被复制
6
上传者