PAT (Advanced Level) 1128~1131:1128N皇后 1129 模拟推荐系统(set<Node>优化) 1130 中缀表达式

1128 N Queens Puzzle(20 分)

题意:N皇后问题。按列依次给定N个皇后的行号,问N个皇后是否能同时不存在行冲突、列冲突和主副对角线冲突。

分析:

1、根据题意一定不存在列冲突,所以要考虑行冲突和主副对角线冲突。(做题时太天真,只考虑了主副对角线)

2、若某皇后的位置由(x,y)表示,则x+y相同的皇后一定处于同一副对角线;x-y+N相同的皇后一定处于同一主对角线。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<iostream>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
const int MAXN = 2000 + 10;
bool vis1[MAXN], vis2[MAXN], vis3[MAXN];
int main(){
    int K;
    scanf("%d", &K);
    while(K--){
        memset(vis1, false, sizeof vis1);
        memset(vis2, false, sizeof vis2);
        memset(vis3, false, sizeof vis3);
        int N, x;
        scanf("%d", &N);
        bool ok = true;
        for(int i = 1; i <= N; ++i){
            scanf("%d", &x);
            if(!vis1[x + i]){//副对角线
                vis1[x + i] = true;
            }
            else{
                ok = false;
            }
            if(!vis2[x - i + N]){//主对角线
                vis2[x - i + N] = true;
            }
            else{
                ok = false;
            }
            if(!vis3[x]){//行
                vis3[x] = true;
            }
            else{
                ok = false;
            }
        }
        if(ok) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
1129 Recommendation System(25 分)

题意:给定某用户的N个查询(query),根据N个query依次出现的顺序,为用户进行最多K个query推荐。推荐的依据为:出现次数多的query在最前面,若出现次数相同,则按query的id递增排序。

分析:结构体Node中存query和query出现的次数,边遍历N个query,边将Node加入set,利用set<Node>排序优化,当加入重复的query时,注意去重。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<iostream>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
const int MAXN = 50000 + 10;
struct Node{
    int value, cnt;
    Node(int v, int c):value(v), cnt(c){}
    bool operator < (const Node&rhs)const{
        return cnt > rhs.cnt || (cnt == rhs.cnt && value < rhs.value);
    }
};
set<Node> st;
int a[MAXN];
int main(){
    int N, K, x;
    scanf("%d%d", &N, &K);
    for(int i = 0; i < N; ++i){
        scanf("%d", &x);
        if(i){
            printf("%d:", x);
            int k = 0;
            for(set<Node>::iterator it = st.begin(); it != st.end(); ++it){
                ++k;
                printf(" %d", (*it).value);
                if(k == K) break;
            }
            printf("\n");
        }
        set<Node>::iterator it = st.find(Node(x, a[x]));
        if(it != st.end()) st.erase(it);
        ++a[x];
        st.insert(Node(x, a[x]));
    }
    return 0;
}
1130 Infix Expression(25 分)

题意:给定一个二叉树,输出其对应的中缀表达式,并用括号表示运算符的优先级。

分析:

1、若某结点不是任何结点的child,则该结点一定是root。通过该方法可找到根结点。

2、叶子结点和表达式的最外层不需要加括号。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<iostream>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
const int MAXN = 20 + 10;
bool ischild[MAXN];
struct Node{
    string value;
    int left, right;
}num[MAXN];
int root;
string solve(int x){
    if(x == -1) return "";
    if(x == root || (num[x].left == -1 && num[x].right == -1)){
        num[x].value = solve(num[x].left) + num[x].value + solve(num[x].right);
    }
    else{
        num[x].value = "(" + solve(num[x].left) + num[x].value + solve(num[x].right) + ")";
    }
    return num[x].value;
}
int main(){
    int N;
    scanf("%d", &N);
    for(int i = 1; i <= N; ++i){
        cin >> num[i].value;
        scanf("%d%d", &num[i].left, &num[i].right);
        if(num[i].left != -1) ischild[num[i].left] = true;
        if(num[i].right != -1) ischild[num[i].right] = true;
    }
    for(int i = 1; i <= N; ++i){
        if(!ischild[i]){
            root = i;
            break;
        }
    }
    printf("%s\n", solve(root).c_str());
    return 0;
}

  

posted @ 2018-09-06 22:40  Somnuspoppy  阅读(180)  评论(0编辑  收藏  举报