• PAT甲级—暴力搜索


    1.BFS

    1091 Acute Stroke (30point(s))

    基础的搜索,但是直接用递归会导致段错误,改用队列之后就不会了,这说明递归调用在空间利用率上还是很吃亏的。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    #include <map>
    #include <queue>
    #include <vector>
    #include <set>
    #define ll long long
    #define inf 0x3f3f3f
    #define pii pair<int, int>
    #define pb push_back
    using namespace std;
    const int maxn = 1e5+100;
    int n, m, l, t;
    int cnt, res, mp[70][200][1500];
    bool vis[70][200][1500];
    void dfs(int x, int y, int z){
        if(x<1||x>l||y<1||y>n||z<1||z>m||mp[x][y][z]!=1||vis[x][y][z]) return;
        vis[x][y][z] = 1, cnt++;
        dfs(x+1, y, z), dfs(x, y+1, z), dfs(x, y, z+1);
        dfs(x-1, y, z), dfs(x, y-1, z), dfs(x, y, z-1);
        return;
    }
    int main(){
        scanf("%d%d%d%d", &n, &m, &l, &t);
        for(int i = 1; i <= l; i++)
            for(int j = 1; j <= n; j++)
                for(int k = 1; k <= m; k++)
                    scanf("%d", &mp[i][j][k]);
        for(int i = 1; i <= l; i++){
            for(int j = 1; j <= n; j++){
                for(int k = 1; k <= m; k++){
                    if(mp[i][j][k]==1&&!vis[i][j][k]) {
                        dfs(i, j, k);
                        if(cnt>=t) res += cnt;
                        cnt = 0;
                    } 
                }
            }
        }
        printf("%d", res);
    }
    Segmentation Fault(DFS)
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    #include <map>
    #include <queue>
    #include <vector>
    #include <set>
    #define ll long long
    #define inf 0x3f3f3f
    #define pii pair<int, int>
    #define pb push_back
    using namespace std;
    const int maxn = 1e5+100;
    struct node{
        int x, y, z;
    };
    int n, m, l, t;
    int cnt, res, mp[70][200][1500];
    bool vis[70][200][1500];
    void bfs(int x, int y, int z){
        queue<node> que;
        que.push({x, y, z});
        int cnt = 0;
        while(!que.empty()){
            node tmp = que.front(); que.pop();
            int x = tmp.x, y = tmp.y, z = tmp.z;
            if(x<1||x>l||y<1||y>n||z<1||z>m||mp[x][y][z]!=1||vis[x][y][z]) continue;
            vis[x][y][z] = 1, cnt++;
            que.push({x+1, y, z}), que.push({x, y+1, z}), que.push({x, y, z+1});
            que.push({x-1, y, z}), que.push({x, y-1, z}), que.push({x, y, z-1});
        }
        if(cnt>=t) res += cnt;
    }
    int main(){
        scanf("%d%d%d%d", &n, &m, &l, &t);
        for(int i = 1; i <= l; i++)
            for(int j = 1; j <= n; j++)
                for(int k = 1; k <= m; k++)
                    scanf("%d", &mp[i][j][k]);
        for(int i = 1; i <= l; i++)
            for(int j = 1; j <= n; j++)
                for(int k = 1; k <= m; k++)
                    if(mp[i][j][k]==1&&!vis[i][j][k])
                        bfs(i, j, k);
        printf("%d", res);
    }
    Accepted(BFS)

    Reference:

    https://github.com/LNoving/PAT

    2.DFS

    1103 Integer Factorization (30分)

    这题就是DFS+剪枝,剪枝不够的话有几个测试样例会超时,主要体现在:

    • 需要事先把各个数的p次方求出来并保存在数组中,避免后面在DFS中反复计算
    • 各项的幂数相同,系数必然会形成排列,可以规定序列为降序,避免出现像3 2 4 1和2 4 3 1这样重复搜索的情况。进一步我们可以限制选取当前项系数的上下界,上限可以设置为上一项的系数值,下限可以通过判断最后能不能用完num来判断

    怎么也没想到这题调试了一下午,最开始没用vector而是用的string,可能因为不那么熟悉string,出现了各种小问题比如初始化之类的,光在这个上面就百度了很久,惭愧。后来发现别人用的vector,就赶紧用这个改了一遍就好了,后面就是超时再优化的问题了

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    #include <map>
    #include <queue>
    #include <vector>
    #include <set>
    #define ll long long
    #define inf 0x3f3f3f
    #define pii pair<int, int>
    #define pb push_back
    using namespace std;
    // const int maxn = 1e5+100;
    int n, k, p;
    int cnt, sum, fac[400];
    //string s("", 400), res("", 400);
    vector<int> now, res;
    int qpow(int a, int n){
        int res = 1;
        while(n){
            if(n&1) res *= a;
            a *= a;
            n >>= 1;
        }
        return res;
    }
    void init(){
        for(int i = 0; i <= sqrt(n); i++)
            fac[i] = qpow(i, p);
    }
    void dfs(int num, int id){
        if(id>k) return;
        else if(num==0&&id==k) {
            if(cnt>sum) res = now, sum = cnt;
            else if(cnt==sum) res = max(res, now);
            return;
        }
        int r = id > 0 ? now[id-1] : pow(num, 1.0/p);
        for(int i = r; i >= 1; i--){
            if((k-id+1)*fac[i] < num) break;
            else if(num-fac[i]<0) continue;
            now.pb(i), cnt += i;
            dfs(num-fac[i], id+1);
            now.pop_back(), cnt -=i;
        }
    }
    int main(){
        scanf("%d%d%d", &n, &k, &p);
        init(), dfs(n, 0);
        if(!res.empty()){
            printf("%d = %d^%d", n, res[0], p);
            for(int i = 1; i <= k-1; i++) printf(" + %d^%d", res[i], p);
        }
        else printf("Impossible");
    }
    View Code
  • 相关阅读:
    八大排序
    链表的合并
    记录B站yxc的背包九讲相关代码
    C++中多态实现
    YOLOV4所用到的一些tricks
    C++中的string 和 stringstream 的知识
    博客园中插入视频
    博客园中插入网页
    面试前必须要知道的【可重入锁 自旋锁】
    面试前必须要知道的【乐观锁 悲观锁】
  • 原文地址:https://www.cnblogs.com/wizarderror/p/14334649.html
Copyright © 2020-2023  润新知