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;
}

浙公网安备 33010602011771号