zoukankan      html  css  js  c++  java
  • 搜索

    搜索大法好

    小木棍:https://www.luogu.org/problem/P1120

    这数据也太加强了吧qaq

    优化:对木棍排序,显然先用长度大的;枚举可能长度时,可能长度是总长度的因数

    然后就是重头戏:如果在一开始,你加入当前最大的木棍,然后你失败了,那么目前为止的方案肯定就不行了,因为这个最大木棍再也没有被用的机会了

    同理,如果你用当前最大填满了,在下一轮中你又失败了,这个肯定也不行

    还有要记得unique啥的,不然扩展层数太多

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<map>
    using namespace std;
    typedef long long ll;
    //typedef int mainint;
    //#define int long long
    typedef double db;
    #define pii pair<int,int>
    #define mp make_pair
    #define llinf 9000000000000000000LL
    #define inf 0x3f3f3f3f
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    #define O(x) cout << #x << " "  << (x) << endl; 
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1; 
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    int n,a[100],sum,L,tot;
    bool flag,ok;
    int vis[101];
    bool cmp(int a,int b) { return a > b; }
    void dfs(int cur,int len,int tot)
    {
        //if(L == 6) printf("%d %d %d
    ",cur,len,tot);
        if(tot == 0) 
        {
            printf("%d",L);
            exit(0);
        }
        else if(cur == n + 1 && len == L) return (void)dfs(1,0,tot - 1);
        for(int i = cur;i <= n;i++)
        {
            if(!vis[a[i]]) continue;
            if(len + a[i] > L) continue;
            vis[a[i]]--;
            if(len + a[i] == L) dfs(1,0,tot - 1);
            else dfs(i,len + a[i],tot);
            vis[a[i]]++;
            if(len == 0 || len + a[i] == L) return;
        }
    }
    int main()
    {
        n = read();
        int mx = 0;
        for(int i = 1;i <= n;i++)     
        { 
            int x = read(); if(x > 50) continue;
            a[++tot] = x;
            vis[x]++;
            sum += a[tot],mx = max(a[tot],mx);
        }
        n = tot;
        sort(a + 1,a + 1 + n,cmp);
        tot = unique(a + 1,a + 1 + n) - a - 1;
        n = tot;
        for(int i = mx;i <= sum;i++)
        {
            if(sum % i) continue;
            L = i;
            ok = flag = 0;
            dfs(1,0,sum / i);
        }
    }
    View Code

    N皇后:https://www.luogu.org/problem/P1562

    维护三个状态:列、左对角线,右对角线,二进制维护

    每到下一层,左对角线左移,右对角线右移(画图即可

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<map>
    using namespace std;
    typedef long long ll;
    //typedef int mainint;
    //#define int long long
    typedef double db;
    #define pii pair<int,int>
    #define mp make_pair
    #define llinf 9000000000000000000LL
    #define inf 0x3f3f3f3f
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    #define O(x) cout << #x << " "  << (x) << endl; 
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1; 
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    int n,a[101];
    int last,ans;
    inline int lowbit(int x) { return x & (-x); }
    void dfs(int cur,int col,int sl,int sr)
    {
        if(cur == n + 1) return (void)(ans += (col == last));
        int pos = (~(col | sl | sr | a[cur])) & last;
        while(pos)
        {
            int p = lowbit(pos);
            pos = pos ^ p;
            dfs(cur + 1,col | p,(sl | p) << 1,(sr + p) >> 1);
        }
    }
    int main()
    {
        n = read();
        last = (1 << n) - 1;
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= n;j++)
            {
                a[i] <<= 1;
                char c;
                cin >> c;
                if(c == '.') a[i] |= 1;
            }
        dfs(1,0,0,0);
        printf("%d",ans);
    }
            
    View Code

    骑士精神:https://www.luogu.org/problem/P2324

    假的A*

    考虑下界剪枝,设置估价函数e,IDA*即可

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<map>
    using namespace std;
    typedef long long ll;
    //typedef int mainint;
    //#define int long long
    typedef double db;
    #define llinf 9000000000000000000LL
    #define inf 0x3f3f3f3f
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    #define O(x) cout << #x << " "  << (x) << endl; 
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1; 
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int dx[]={0,1,1,-1,-1,2,2,-2,-2};
    const int dy[]={0,2,-2,2,-2,1,-1,1,-1};
    const int goal[7][7]={
        {0,0,0,0,0,0},
        {0,1,1,1,1,1},
        {0,0,1,1,1,1},
        {0,0,0,2,1,1},
        {0,0,0,0,0,1},
        {0,0,0,0,0,0}
    };
    bool ok;
    int mp[7][7];
    inline int e()
    {
        int res = 0;
        for(int i = 1;i <= 5;i++)
            for(int j = 1;j <= 5;j++)
                if(mp[i][j] != goal[i][j]) res++;
        return res;
    }
    void dfs(int dep,int x,int y,int mdep)
    {
        if(dep == mdep) return (void)(ok = (e() == 0));
        for(int i = 1;i <= 8;i++)
            {
                if(ok) return;
                int nx = x + dx[i],ny = y + dy[i];
                if(nx < 1 || nx > 5 || ny < 1 || ny > 5) continue;
                swap(mp[x][y],mp[nx][ny]);
                if(dep + e() <= mdep) dfs(dep + 1,nx,ny,mdep);
                swap(mp[x][y],mp[nx][ny]);
            }    
    }
    int main()
    {
        int t = read();
        while(t--)
        {
            ok = 0;
            int sx,sy;
            char x;
            for(int i = 1;i <= 5;i++)
                for(int j = 1;j <= 5;j++)
                {
                    cin >> x;
                    if(x == '*') mp[i][j] = 2,sx = i,sy = j;
                    else mp[i][j] = x - '0';
                }
            if(!e()) {printf("0
    "); continue; }
            for(int i = 1;i <= 15;i++)
            {
                dfs(0,sx,sy,i);
                if(ok)
                {
                    printf("%d
    ",i);
                    break;
                }
            }
            if(!ok) printf("-1
    ");
        }
    }
    View Code
  • 相关阅读:
    委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)
    C#异步:实现一个最简单的异步
    关于Thread.IsBackground属性的理解(转载)
    C# 中的多线程(转载)
    个人对AutoResetEvent和ManualResetEvent的理解(转载)
    C#线程系列讲座(4):同步与死锁
    Nginx location 配置踩坑过程分享
    微信扫码登录网页实现原理
    负载均衡SLB
    Tomcat学习
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/11258991.html
Copyright © 2011-2022 走看看