zoukankan      html  css  js  c++  java
  • 【题解】 Codeforces 919F A Game With Numbers(拓扑排序+博弈论+哈希)

    懒得复制,戳我戳我

    Solution:


    说一点之前打错的地方:

    • 连边存的是hash后的数组下标
     if(ans[ num( C[a.hash()] , C[b.hash()] ) ]==1){
          if(f==0)printf("Alice
    ");else printf("Bob
    ");
          continue;
        }
        if(ans[ num( C[a.hash()] , C[b.hash()] ) ]==-1){
          if(f==0)printf("Bob
    ");else printf("Alice
    ");
          continue;
        }
    
    • 每个点存的是A状态与B状态,A操作的必胜还是必输态
    • 然后就是一个要注意的点:我们是反向存边,由后状态推向先状态,如果后状态为必输态,那么先状态一定为必胜态,如果先状态的所有可以达到的后状态都为必胜态,那么这个先状态是必输态
    • 这题思路比较明确,就是一些代码细节要注意吧,还有因为这题学会了(Struct)的骚操作

    Code:

    //It is coded by Ning_Mew on 3.27
    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=400000+10;
    
    int n,f;
    int S[maxn],C[maxn],ct=0;
    int head[maxn],cnt=0,in[maxn],ans[maxn];
    struct Edge{int nxt,to;}edge[(maxn<<6)+5];
    
    void add(int from,int to){
      in[to]++;
      edge[++cnt].nxt=head[from];
      edge[cnt].to=to;
      head[from]=cnt;
    }
    
    //bool cmp(const int &xx,const int &yy){return xx<yy;}
    struct hs{
      int a[8];
      hs(){memset(a,0,sizeof(a));}
      hs(int x){for(int i=7;i>=0;i--){a[i]=x%5;x=x/5;}}
      hs(int *_a){for(int i=7;i>=0;i--)a[i]=_a[i];}
      void rd(){for(int i=0;i<=7;i++)scanf("%d",&a[i]);}
      void st(){sort(a,a+8);}
      int hash(){
        int ans=0;
        for(int i=0;i<=7;i++)ans=ans*5+a[i];
        return ans;
      }
    };
    
    void dfs(int pl,int last,int h){
      if(pl==8){++ct;S[ct]=h;C[h]=ct;return;}
      for(int i=last;i<=4;i++)dfs(pl+1,i,h*5+i);
    }
    int num(int x,int y){return (x-1)*ct+(y-1);}
    void prework(){
      dfs(0,0,0);
      for(int i=1;i<=ct;i++){
        for(int j=1;j<=ct;j++){
          hs a(S[i]),b(S[j]);
          for(int pi=0;pi<=7;pi++)if(a.a[pi]){
    	  for(int pj=0;pj<=7;pj++)if(b.a[pj]){
    	      hs c(a.a);
    	      c.a[pi]=(a.a[pi]+b.a[pj])%5;
    	      c.st();int tmp=C[c.hash()];
    	      add( num( j,tmp ),num( i,j ) );
    	    }
    	}
        }
      }
      queue<int>Q;
      while(!Q.empty())Q.pop();
      //-1 lose 1 win 0 deal
      for(int i=2;i<=ct;i++)ans[ num(i,1) ]=-1,Q.push( num(i,1) );
      while(!Q.empty()){
        int u=Q.front();Q.pop();
        for(int i=head[u];i!=0;i=edge[i].nxt){
          int v=edge[i].to;
          if(ans[v]!=0)continue;
          if(ans[u]==-1){ans[v]=1;Q.push(v);}
          else{
    	in[v]--;
    	if(in[v]==0){ans[v]=-1;Q.push(v);}
          }
        }
      }return;
    }
    
    int main(){
      memset(ans,0,sizeof(ans));
      prework();
      scanf("%d",&n);
      hs a,b;
      for(int i=1;i<=n;i++){
        scanf("%d",&f);
        a.rd();b.rd();a.st();b.st();
        if(f==1)swap(a,b);
        if(ans[ num( C[a.hash()] , C[b.hash()] ) ]==1){
          if(f==0)printf("Alice
    ");else printf("Bob
    ");
          continue;
        }
        if(ans[ num( C[a.hash()] , C[b.hash()] ) ]==-1){
          if(f==0)printf("Bob
    ");else printf("Alice
    ");
          continue;
        }
        printf("Deal
    ");
      }
      return 0;
    }
    
    
  • 相关阅读:
    Head first java chapter 8 接口与抽象类
    Head first java chapter 4 对象的行为
    Head first java chapter 3认识变量
    Head first java chapter 2 拜访对象村
    Head first java chapter 1
    Invalid left-hand side in assignment
    swtich多个case使用同一操作
    CSS绘制小三角
    超出文字出现省略号不换行
    css代码实现列表等宽
  • 原文地址:https://www.cnblogs.com/Ning-Mew/p/8658440.html
Copyright © 2011-2022 走看看