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 "); else printf("NO "); } 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(" "); } 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 ", solve(root).c_str()); return 0; }