BZOJ3979 : [WF2012]infiltration

答案是$O(\log n)$级别的,故答案不超过6。

当答案是12345时,暴力枚举+压位检验即可,否则直接输出6。

时间复杂度$O(n^5)$。

 

#include<cstdio>
#define N 80
#define rep(i,n) for(int i=0;i<n;i++)
typedef unsigned int U;
int n,T;char s[N];
struct P{
  U x,y,z;
  P(){x=y=z=0;}
  P(U _x,U _y,U _z){x=_x,y=_y,z=_z;}
  inline P operator|(const P&b){return P(x|b.x,y|b.y,z|b.z);}
  inline void set(int p){
    if(p<32){x|=1U<<p;return;}
    p-=32;
    if(p<32){y|=1U<<p;return;}
    z|=1U<<(p-32);
  }
  inline int cnt(){return __builtin_popcount(x)+__builtin_popcount(y)+__builtin_popcount(z);}
}g[N],S;
inline bool one(){
  rep(i,n)if(g[i].cnt()==n)return 1;
  return 0;
}
inline bool two(){
  rep(i,n)rep(j,i)if((g[i]|g[j]).cnt()==n)return 1;
  return 0;
}
inline bool three(){
  rep(i,n)rep(j,i)rep(k,j)if((g[i]|g[j]|g[k]).cnt()==n)return 1;
  return 0;
}
inline bool four(){
  rep(i,n)rep(j,i)rep(k,j)rep(l,k)if((g[i]|g[j]|g[k]|g[l]).cnt()==n)return 1;
  return 0;
}
inline bool five(){
  rep(i,n)rep(j,i)rep(k,j)rep(l,k)rep(m,l)if((g[i]|g[j]|g[k]|g[l]|g[m]).cnt()==n)return 1;
  return 0;
}
int main(){
  while(~scanf("%d",&n)){
    printf("Case %d: ",++T);
    rep(i,n){
      scanf("%s",s);
      g[i]=P();
      g[i].set(i);
      rep(j,n)if(s[j]=='1')g[i].set(j);
    }
    if(one()){puts("1");continue;}
    if(two()){puts("2");continue;}
    if(three()){puts("3");continue;}
    if(four()){puts("4");continue;}
    if(five()){puts("5");continue;}
    puts("6");
  }
  return 0;
}

  

posted @ 2016-07-07 00:08  Claris  阅读(251)  评论(0编辑  收藏  举报