zoukankan      html  css  js  c++  java
  • 2019年华南理工大学程序设计竞赛(春季赛) B 修仙时在做什么?有没有空?可以来炼丹吗?(思维建图搜索)

    https://ac.nowcoder.com/acm/contest/625/B

    分析:

    全部的状态只有1<<18 个 , 所以我们可以预处理 f[u][j] , 然后建立出全部的u可以转移的状态的状态图;

    有优先队列去搜索

    这里需要注意一个坑点 , 数组f[i][j] , 是不能开到long long ,这样会爆内存;可是 f[i][j-1]* f[i][j-1] 这个操作会爆int ,所以我们需要将

    f[i][j-1]* f[i][j-1] 变成long long   1ll*f[i][j-1]* f[i][j-1] 然后再去 mod 

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 1<<18;
    const int mod = 19260817;
    const int INF = 0x3f3f3f3f;
    
    bool vabook[maxn],vis[maxn];
    int f[maxn][20];
    int fa[maxn];
    int dis[maxn];
    struct no
    {
        int v;
       int  val;
        bool operator < (const no &x) const
        {
            return x.val<val;
        }
    }P;
    vector<no>G[maxn];
    priority_queue<no> que;
    int main()
    {
        int n;scanf("%d",&n);
        bool T=0;
        int x ;
        for(int i=1 ; i<=n ; i++)
        {
            scanf("%d",&x);
            if(vabook[x]) T=1;
                vabook[x]=1;
        }
        if(T) {puts("0");return 0;} ///如果给出的数有重复出现 , 肯定是0更优
    
        for(int i=0 ; i<maxn ; i++)  ///预处理出全部的 f[i][j]
        {
            f[i][0]=i;
            for(int j=1 ; j<18 ; j++)/// a^4=a^2 * a^2 , a^8=a^4*a^4;
            {
                f[i][j] = (1ll*f[i][j-1]* f[i][j-1]) %mod;///先转化为 long long 再去mod
            }
    
    
        }
        for(int u=0 ; u<maxn ; u++)
        {
            for(int j=0 ; j<18 ; j++)
            {
                int v=u^(1<<j);
                x = max(u,v);
                G[u].push_back({v , f[x][j]+1});///建立一个图 , 把u 可以转去的状态于价值都记录
            }
            if(vabook[u])///这是我拥有的点
            {
                fa[u]=u;
                dis[u]=0;
                que.push({u,0});
            }
            else
            {
                fa[u]=-1;
                dis[u]=INF;
            }
        }
        ll ans=0x3f3f3f3f;
        //DJ最短路
        while(!que.empty()) 
        {
            P=que.top();
            que.pop();
            int u=P.v;
            if(P.val>=ans) break;///如果当前的状态最小的价值都小过ans , 就不用跟新了
            if(vis[u]) continue;
            vis[u]=1;
            for(int i=0 ; i<G[u].size() ; i++)
            {
                int v=G[u][i].v;
                int w=G[u][i].val;
    
                if(fa[v]!=-1 && fa[v]!=fa[u])
                {
                    ans=min(ans,1ll*(dis[v]+w+dis[u]));
                    //ans%=mod;
                }
    
                if(dis[v] > w+dis[u])
                {
                    dis[v]=w+dis[u];
                    fa[v]=fa[u];
    
                    que.push({v,dis[v]});
                }
            }
        }
        printf("%lld
    ",ans%mod);
        return 0;
    }
    View Code
  • 相关阅读:
    5th-个人总结(Alpha阶段)
    4th-结对编程2
    3rd-Bing Dict使用分析
    1st_homework_SE--四则运算题目生成器
    附加作业
    个人作业(3)----个人总结(Alpha阶段)
    结对作业(2)----单元测试
    个人作业(2)----英语学习APP案例分析
    结对作业(1)----基于GUI的四则运算
    (Alpha)个人总结
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/10716315.html
Copyright © 2011-2022 走看看