美文网首页
PAT A 1148 1149 1150 1151

PAT A 1148 1149 1150 1151

作者: 大美mixer | 来源:发表于2018-11-24 21:39 被阅读0次

    1148 枚举

    题目大意: 假设有2个狼人,至少有一个,但是不是全部 在说谎 ,,那岂不是只有1个在说谎。至少有2人说谎,也就是说村民也有可能说谎 ,且至少有一个村民在说谎 。

    #include<stdio.h>
    #include<vector>
    using namespace std;
    
    typedef struct node{
        bool flag;
        int id;
    }node;
     
    int main(){
        int n;
        scanf("%d", &n); 
        vector<node> v(n+1);
        for(int i=1;i<=n;i++){
            char s[2];
            scanf("%s",s);
            v[i].flag =  s[0]=='+' ? false : true;//是狼人就是true 
            v[i].id = s[1] - '0';
        }
        int fake_num = 0;//统计说谎人数 
        int flag = false;
        //选取两个狼人 
        for(int i = 1; i <= n; i++){
            if(flag == false){ 
                for(int j = i+1; j <= n; j++){
                    bool judge[105] = {false};
                    fake_num = 0;
                    judge[i] = judge[j] = true; 
                    //先判断两个狼人说话是否符合条件 
                    if(v[i].flag != judge[ v[i].id ]) fake_num++;
                    if(v[j].flag != judge[ v[j].id ]) fake_num++;
                    //printf("fake_num:%d ",fake_num);
                    if(fake_num != 1) continue;
                    //然后判断村民说话是否符合条件 
                    for(int k = 1; k <= n; k++){
                        if(k != i && k != j){
                            if(v[k].flag != judge[ v[k].id ]) fake_num++;
                        } 
                    }
                    //printf(" %d\n",fake_num);
                    if(fake_num == 2){
                        printf("%d %d", i, j);
                        flag = true;
                        break;
                    }
                }
            }else{
                break; 
            } 
        }
        if(flag == false){
            printf("No Solution\n");
        }
        return 0;
    }
    

    结果: 有一个运行时错误,我还没找出来5555555555555~

    1149 STL

    incompatible 不相容的

    #include<map>
    #include<vector>
    #include<iostream>
    using namespace std;
     
    int main(){
        int n, m;
        scanf("%d %d", &n, &m);
        map<int, vector<int> > map;
        for(int i=0;i<n;i++){
            int a,b;
            cin>>a>>b;
            map[a].push_back(b);
            map[b].push_back(a);
        }
        for(int i=0;i<m;i++){
            int k;
            scanf("%d", &k);
            vector<int> v(k);
            int table[100001] = {0};
            for(int j=0;j<k;j++){
                cin>>v[j];
                table[v[j]] = 1;
            }
            bool flag = true;
            for(int j=0;j<k && flag;j++){   
                for(int q=0; q < map[v[j]].size();q++){
                    if(table[map[v[j]][q]] == 1){
                        flag = false;
                        break;
                    }
                }
            }
            if( flag == true) cout<<"Yes\n";
            else cout<<"No\n";
        }
        return 0;
    } 
    

    1150 图论

    combinatorial 组合的
    operations research 运筹学
    旅行商环路

    #include<stdio.h>
    #include<set>
    using namespace std;
    int main(){
        int n,m,k;
        scanf("%d %d", &n, &m);
        int e[205][205];
        for(int i=0;i<m;i++){
            int a,b,t;
            scanf("%d %d %d", &a, &b, &t);
            e[a][b] = e[b][a] = t;
        }
        scanf("%d",&k);
        int minid = 0, mindis = 99999; //100*200=20000
        for(int i=1;i<=k;i++){
            int t, sum = 0, st,sst, en;
            scanf("%d", &t);
            bool flag = true, no = false;
            scanf("%d", &st);
            sst = st;
            set<int> s;
            for(int j=1; j<t; j++){
                scanf("%d", &en);
                s.insert(en);
                if(e[st][en] == 0){
                    no = true;
                    flag = false;
                }
                sum += e[st][en];
                st = en;
            }
            if(s.size() != n){//没有遍历所有节点 
                flag = false; 
            }
            if(no){
                printf("Path %d: NA (Not a TS cycle)\n",i);
            }else if(sst != en || flag == false){
                printf("Path %d: %d (Not a TS cycle)\n", i, sum);
            }else if( t == n+1){
                printf("Path %d: %d (TS simple cycle)\n", i, sum);
            }else{
                printf("Path %d: %d (TS cycle)\n", i, sum);
            }
            if(flag){
                if(mindis > sum){
                    mindis = sum;
                    minid = i;
                }
            }
        }
        printf("Shortest Dist(%d) = %d", minid, mindis);
        return 0;
    } 
    

    1151 树

    题目大意: 知道先序中序,找出最近祖先

    #include<stdio.h>
    #include<vector>
    using namespace std;
    
    int m,n;
    int p_in, q_in;
    int p_pre, q_pre;
    int anc;
    vector<int> inorder;
    vector<int> preorder;
    
    int find(int st_in, int en_in, int st_pre, int en_pre){
        //首先找到根节点
        int root;
        for(int i=st_in; i<=en_in; i++){
            if(inorder[i] == preorder[st_pre]){
                root = i;
                break;
            }
        }
        if(p_in < root && q_in < root){//都在左子树 
            find(st_in, root-1, st_pre+1, st_pre+(root-st_in)+1);
        }else if(p_in > root && q_in > root){//都在右子树 
            find(root+1, en_in, root+1, en_pre-(en_in-root)+1);
        }else{
            return inorder[root];
        }
    } 
    
    int main(){
        
        scanf("%d %d", &m, &n);
        
        inorder.resize(n);
        preorder.resize(n);
        
        for(int i=0;i<n;i++){
            scanf("%d", &inorder[i]);
        }
        for(int i=0;i<n;i++){
            scanf("%d", &preorder[i]);
        }
        for(int i=0;i<m;i++){
            int u, v;
            scanf("%d %d", &u, &v);
            //先判断u,v是否存在 
            bool exist_u = true, exist_v = true;
            if( u <= 0 || u > n){
                exist_u = false;
            }
            if( v <= 0 || v > n){
                exist_v = false;
            }
            if(exist_u == false && exist_v == false){
                printf("ERROR: %d and %d are not found.\n", u, v);
                continue;
            }else if(exist_u == false){
                printf("ERROR: %d is not found.\n", u);
                continue;
            }else if(exist_v == false){
                printf("ERROR: %d is not found.\n", v);
                continue;
            }
            //首先在序列中定位
            for(int i=0;i<n;i++){
                if(inorder[i] == u){
                    p_in = i;
                }
                if(inorder[i] == v){
                    q_in = i;
                }
            }
            for(int i=0;i<n;i++){
                if(preorder[i] == u){
                    p_pre = i;
                }
                if(preorder[i] == v){
                    q_pre = i;
                }
            } 
             
            anc = find(0,n-1,0,n-1);
            
            if( anc != u && anc != v){
                printf("LCA of %d and %d is %d.\n", u, v, anc);
            }else if(anc == u){
                printf("%d is an ancestor of %d.\n", u, v);
            }else{
                printf("%d is an ancestor of %d.\n", v, u);
            }
        }
        
        return 0;
    } 
    

    结果: 超时可以用map解决,还有2错没找到!!

    部分正确

    然后我就找到了!
    原来编号不一定按照顺序。细节啊!自以为是啊!于是代码变成了这样:

    #include<stdio.h>
    #include<vector>
    #include<map> 
    using namespace std;
    
    int m,n;
    int p_in, q_in;
    int p_pre, q_pre;
    int anc;
    map<int, bool> mp;
    vector<int> inorder;
    vector<int> preorder;
    
    int find(int st_in, int en_in, int st_pre, int en_pre){
        //首先找到根节点
        int root;
        for(int i=st_in; i<=en_in; i++){
            if(inorder[i] == preorder[st_pre]){
                root = i;
                break;
            }
        }
        if(p_in < root && q_in < root){//都在左子树 
            find(st_in, root-1, st_pre+1, st_pre+(root-st_in)+1);
        }else if(p_in > root && q_in > root){//都在右子树 
            find(root+1, en_in, root+1, en_pre-(en_in-root)+1);
        }else{
            return inorder[root];
        }
    } 
    
    int main(){
        
        scanf("%d %d", &m, &n);
        
        inorder.resize(n);
        preorder.resize(n);
        
        for(int i=0;i<n;i++){
            scanf("%d", &inorder[i]);
            mp[inorder[i]] = true;
        }
        for(int i=0;i<n;i++){
            scanf("%d", &preorder[i]);
        }
        for(int i=0;i<m;i++){
            int u, v;
            scanf("%d %d", &u, &v);
            //先判断u,v是否存在 
            bool exist_u = true, exist_v = true;
            if( mp[u] != true ){
                exist_u = false;
            }
            if( mp[v] != true ){
                exist_v = false;
            }
            if(exist_u == false && exist_v == false){
                printf("ERROR: %d and %d are not found.\n", u, v);
                continue;
            }else if(exist_u == false){
                printf("ERROR: %d is not found.\n", u);
                continue;
            }else if(exist_v == false){
                printf("ERROR: %d is not found.\n", v);
                continue;
            }
            //首先在序列中定位
            for(int i=0;i<n;i++){
                if(inorder[i] == u){
                    p_in = i;
                }
                if(inorder[i] == v){
                    q_in = i;
                }
            }
            for(int i=0;i<n;i++){
                if(preorder[i] == u){
                    p_pre = i;
                }
                if(preorder[i] == v){
                    q_pre = i;
                }
            } 
             
            anc = find(0,n-1,0,n-1);
            
            if( anc != u && anc != v){
                printf("LCA of %d and %d is %d.\n", u, v, anc);
            }else if(anc == u){
                printf("%d is an ancestor of %d.\n", u, v);
            }else{
                printf("%d is an ancestor of %d.\n", v, u);
            }
        }
        
        return 0;
    } 
    

    就只剩超时的问题了!

    改进可以参考下面这种方法:

    #include<stdio.h>
    #include<vector>
    #include<map>
    using namespace std;
    
    int main(){
        int m,n;
        scanf("%d %d", &m, &n);
        vector<int> preorder(n);
        map<int, bool> mp;
        for(int i=0;i<n;i++){
            scanf("%d", &preorder[i]);
            mp[preorder[i]] = true;
        }
        
        for(int i=0;i<m;i++){
            int u,v;
            scanf("%d %d", &u, &v);
            if(mp[u] == false && mp[v] == true){
                printf("ERROR: %d is not found.\n", u);
                continue;
            }else if(mp[v] == false && mp[u] == true){
                printf("ERROR: %d is not found.\n", v);
                continue;
            }else if(mp[v] == false && mp[u] == false){
                printf("ERROR: %d and %d are not found.\n", u, v);
                continue;
            }
            int anc;
            for(int j=0;j<n;j++){
                anc = preorder[j];
                if( (anc >=u && anc <=v ) || (anc >=v && anc <=u )){
                    break;
                }
            }
            if(anc == u){
                printf("%d is an ancestor of %d.\n", u, v);
            }else if(anc == v){
                printf("%d is an ancestor of %d.\n", v, u);
            }else{
                printf("LCA of %d and %d is %d.\n", u, v, anc);
            }
        }
        return 0;
    } 
    

    解决!

    相关文章

      网友评论

          本文标题:PAT A 1148 1149 1150 1151

          本文链接:https://www.haomeiwen.com/subject/ncxuqqtx.html