zoukankan      html  css  js  c++  java
  • P3005 [USACO10DEC]槽的游戏 [搜索]

    槽的游戏

    题目描述见链接 .


    color{grey}{最初想法}

    直接上 高斯消元, 发现只能得到 70pts70pts,

    代码,

    #include<bits/stdc++.h>
    #define reg register
    
    const double eps = 1e-12;
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 105;
    
    int N;
    int M;
    
    double A[maxn][maxn];
    
    char Tmp[25];
    
    int Fuck(){
    
            int t = 1;
            for(reg int i = 1; i <= M && t <= N; i ++, t ++){
                    int max_id = t;
                    for(reg int j = t+1; j <= M; j ++) if(A[j][i] > A[max_id][i]) max_id = j;
                    if(!A[max_id][i]){ t --; continue ; }
                    std::swap(A[max_id], A[t]);
                    for(reg int j = N+1; j >= i; j --) A[t][j] /= A[t][i];
                    if(A[t][i] < 0) for(reg int j = 1; j <= N+1; j ++) A[t][j] = -A[t][j];
                    for(reg int j = t+1; j <= M; j ++){
                            if(!A[j][i]) continue ;
                            for(reg int k = N+1; k >= i; k --) A[j][k] -= A[j][i] * A[t][k];
                    }
            }
            t --;
            for(reg int i = t; i >= 1; i --)
                    for(reg int j = i+1; j <= N; j ++) A[i][N+1] -= A[j][N+1]*A[i][j], A[i][j] = 0;
            for(reg int i = t+1; i <= N; i ++) if(fabs(A[i][N+1]) > eps) return -1;
            if(t < N) return 0;
            return 1;
    }
    
    int main(){
            N = read(), M = read();
            for(reg int i = 1; i <= M; i ++){
                    scanf("%s", Tmp+1);
                    for(reg int j = 1; j <= N; j ++) A[i][j] = Tmp[j] - '0';
                    A[i][N+1] = read();
            }
            int flag = Fuck();
            if(flag == -1) printf("IMPOSSIBLE
    ");
            else if(flag == 0) printf("NOT UNIQUE
    ");
            else for(reg int i = 1; i <= N; i ++) printf("%.0lf", fabs(A[i][N+1]));
            return 0;
    }
    

    原来是因为当方程的个数小于 NN 个, 且仅有一种合法方案使得方程组成立时, 高斯消元 是判其多解的 .

    例如这组数据:

    5 1
    11111 5
    

    color{red}{正解部分}

    直接将每个方程化为二进制形式, 暴力搜索, 搜索 时剪剪枝就可以 AcAc 了 …


    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 105;
    
    int N;
    int M;
    int flag;
    int flag_2;
    int ans[maxn];
    int res[maxn];
    
    char Smp[22];
    
    struct Node{ int max_bit, zt, val; } A[maxn];
    
    bool cmp(Node a, Node b){ return a.max_bit < b.max_bit; }
    
    bool check(const int &lev){
            for(reg int i = 1; i <= M; i ++){
                    if(A[i].max_bit > lev) break ;
                    int s = 0;
                    for(reg int j = 1; j <= N; j ++) if(A[i].zt & (1<<j-1)) s += ans[j];
                    if(s != A[i].val) return 0;
            }
            return 1;
    }
    
    void DFS(int k, int zt){
            if(flag_2) return ;
            if(k == N+1){
                    if(check(k+1)){
                            if(flag){ flag_2 = 1; return ; }
                            flag = 1;
                            for(reg int i = 1; i <= N; i ++) res[i] = ans[i];
                    }
                    return ;
            }
            ans[k] = 1;
            if(check(k)) DFS(k+1, zt|(1<<k-1));
            ans[k] = 0; DFS(k+1, zt);
    }
    
    int main(){
            scanf("%d%d", &N, &M);
            for(reg int i = 1; i <= M; i ++){
                    scanf("%s", Smp+1);
                    for(reg int j = 1; j <= N; j ++){
                            A[i].zt |= ((Smp[j]-'0') << (j-1));
                            if(Smp[j] == '1') A[i].max_bit = j;
                    }
                    scanf("%d", &A[i].val);
            }
            std::sort(A+1, A+M+1, cmp);
            DFS(1, 0);
            if(!flag) printf("IMPOSSIBLE
    ");
            else if(flag_2) printf("NOT UNIQUE
    ");
            else for(reg int i = 1; i <= N; i ++) printf("%d", res[i]);
            return 0;
    }
    
  • 相关阅读:
    jq判断input 复选框有没有选
    jq根据id替换修改或添加css属性
    cookie和session的关系和区别
    tp5 统一返回json格式
    tp5 上传图片(自定义图片路径)
    tp5 生成随机数
    tp5 删除图片以及文件
    tp5 上传视频方法
    tp5 跨域问题
    js替换div里的内容
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822433.html
Copyright © 2011-2022 走看看