2017.6.11 校内模拟赛
Posted ZlycerQan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017.6.11 校内模拟赛相关的知识,希望对你有一定的参考价值。
题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛
T1
自己在纸上模拟一下后就会发现
可以用栈来搞一搞事情
受了上次zsq 讲的双栈排序的启发。。
具体就是将原盘子大小copy一下排个序
用两个指针维护两个数组(原数据 和 排序后的数据), 即分为1数据和2数组
将小于1指针指向的数据的2数组中的数据全部压入栈中
后进行消除, 将栈栈顶元素与当前1数组中的1指针指向的元素进行比较
相同则消除
后重复过程
直至指针超过N
后判断一下是否两个指针都超过了N。。。
#include <algorithm> #include <cstring> #include <cstdio> #include <stack> #define Max 100090 void read (int &now) { now = 0; register char word = getchar (); while (word < ‘0‘ || word > ‘9‘) word = getchar (); while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; word = getchar (); } } int N, M; int dish[Max]; int data[Max]; class Stack_Type { private : int Stack[Max]; int Top_Cur; public : inline void Clear () { Top_Cur = 0; } inline void Pop () { Top_Cur --; } bool Empty () { return Top_Cur == 0; } inline int Top () { return Stack[Top_Cur]; } inline void Push (int x) { Stack[++ Top_Cur] = x; } }; Stack_Type Stack; int main (int argc, char *argv[]) { freopen ("disk.in", "r", stdin); freopen ("disk.out", "w", stdout); int T; for (; scanf ("%d", &N) != EOF; ) { memset (dish, 0, sizeof dish); memset (data, 0, sizeof data); bool flag = false; Stack.Clear (); for (int i = 1; i <= N; i ++) { read (dish[i]); data[i] = dish[i]; } std :: sort (data + 1, data + 1 + N); register int pos_1 = 1, pos_2 = 1; for (; (pos_1 <= N || pos_2 <= N) && (Stack.Empty () || dish[pos_1] >= Stack.Top ()); ) { for (; pos_2 <= N && dish[pos_1] >= data[pos_2]; ) Stack.Push (data[pos_2 ++]); for (; !Stack.Empty () && pos_1 <= N && Stack.Top() == dish[pos_1]; Stack.Pop (), pos_1 ++); } if (pos_1 > N && pos_2 > N) printf ("Y\n"); else printf ("J\n"); } return 0; }
T2
这个题估计随便乱搞搞就能A吧。。
看机房里众dalao 以各种奇怪的姿势AC此题。。
思路:枚举每个点,算出对角线边缘的两个分别进行二分, 分别找出两个符合条件的边界点, 乘一乘就好了。。
写了四个二分我也是醉了。。。写完后才想起来有 lower_bound 这个东西。。。
#include <algorithm> #include <cstdio> #define Max 10010 void read (int &now) { now = 0; register char word = getchar (); bool temp = false; while (word < ‘0‘ || word > ‘9‘) { if (word == ‘-‘) temp = true; word = getchar (); } while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; word = getchar (); } if (temp) now = -now; } struct Data_ { int x, y; Data_ (int __x, int __y) : x (__x), y (__y) {}; Data_ () {}; bool operator < (const Data_ &now) const { if (this->x == now.x) return this->y < now.y; return this->x < now.x; } }; inline int abs (int x) { return x < 0 ? -x : x; } long long Answer; int N; bool Judge (Data_ now_1, Data_ now_2) { if (now_2.y <= now_1.y) return true; if (abs (now_1.x + now_1.y + now_2.x - now_2.y) % 2 == 1) return true; if (abs (now_2.x - now_1.x + now_1.y + now_2.y) % 2 == 1) return true; return false; } Data_ point[Max]; bool ErFen_Judge (int now, int x, int y) { Data_ res (x, y); return point[now] < res; } bool ErFen_Re_Judge (int now, int x, int y) { if (point[now].x == x) return point[now].y > y; return point[now].x > x; } int main (int argc, char *argv[]) { freopen ("car.in", "r", stdin); freopen ("car.out", "w", stdout); read (N); for (int i = 1; i <= N; i ++) { read (point[i].x); read (point[i].y); } std :: sort (point + 1, point + 1 + N); int l, r, Mid; for (int i = 1; i <= N; i ++) for (int j = i + 1; j <= N; j ++) { if (point[i].x == point[j].x && point[i].y == point[j].y) continue ; if (Judge (point[i], point[j])) continue; register int now_x = (point[i].x + point[i].y + point[j].x - point[j].y) >> 1; register int now_y = (point[j].x - point[i].x + point[i].y + point[j].y) >> 1; l = 0; r = N + 1; while (l + 1 < r) { Mid = l + r >> 1; if (ErFen_Judge (Mid, now_x, now_y)) l = Mid; else r = Mid; } int Result_1 = l; l = 0; r = N + 1; while (l + 1 < r) { Mid = l + r >> 1; if (ErFen_Re_Judge (Mid, now_x, now_y)) r = Mid; else l = Mid; } Result_1 = l - Result_1; now_x = (point[i].x - point[i].y + point[j].x + point[j].y) >> 1; now_y = (point[i].x + point[i].y - point[j].x + point[j].y) >> 1; l = 0; r = N + 1; while (l + 1 < r) { Mid = l + r >> 1; if (ErFen_Judge (Mid, now_x, now_y)) l = Mid; else r = Mid; } int Result_2 = l; l = 0; r = N + 1; while (l + 1 < r) { Mid = l + r >> 1; if (ErFen_Re_Judge (Mid, now_x, now_y)) r = Mid; else l = Mid; } Result_2 = l - Result_2; Answer += (long long) Result_1 * Result_2; } printf ("%lld", Answer); return 0; }
T3
主席树 + 权值线段树 板子题。。
#include <algorithm> #include <cstdio> #define Max 40000 void read (int &now) { now = 0; register char word = getchar (); while (word > ‘9‘ || word < ‘0‘) word = getchar (); while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; word = getchar (); } } void read_long_long (long long &now) { now = 0; register char word = getchar (); while (word > ‘9‘ || word < ‘0‘) word = getchar (); while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; word = getchar (); } } struct Tree_Data { int key; int l, r; int Mid; }; Tree_Data tree[Max * 20]; Tree_Data node[Max]; int N, M; class Tree_Type { private : int Count_; int People_Count; void __Build_ (Tree_Data &now, int l, int r) { if (l == r) return ; now.Mid = l + r >> 1; now.l = ++ Count_; __Build_ (tree[now.l], l, now.Mid); now.r = ++ Count_; __Build_ (tree[now.r], now.Mid + 1, r); } void __Updata_ (Tree_Data &Pre, Tree_Data &now, int l, int r,int pos) { if (l == r) { now.key ++; return ; } now.Mid = Pre.Mid; if (pos <= now.Mid) { now.r = Pre.r; now.l = ++ Count_; __Updata_ (tree[Pre.l], tree[now.l], l, now.Mid, pos); } else { now.l = Pre.l; now.r = ++ Count_; __Updata_ (tree[Pre.r], tree[now.r], now.Mid + 1, r, pos); } now.key = tree[now.l].key + tree[now.r].key; } int __Query_ (Tree_Data &Pre, Tree_Data &now, int l, int r, int k) { if (l == r) return l; int res = tree[now.l].key - tree[Pre.l].key; if (k <= res) return __Query_ (tree[Pre.l], tree[now.l], l, now.Mid, k); else return __Query_ (tree[Pre.r], tree[now.r], now.Mid + 1, r, k - res); } public : Tree_Type () { Count_ = 0; People_Count = 0; } inline void Build (int l, int r) { __Build_ (node[0], l, r); return ; } inline void Updata (int now, int pos) { __Updata_ (node[now - 1], node[now], 1, N, pos); return ; } inline int Query (int k) { return __Query_ (node[0], node[k], 1, N, ++ People_Count); } }; Tree_Type President_Tree; long long __rank[Max]; long long number[Max]; int main (int argc, char *argv[]) { freopen ("rollcall.in", "r", stdin); freopen ("rollcall.out", "w", stdout); read (N); read (M); for (int i = 1; i <= N; __rank[i] = number[i], i ++) read_long_long (number[i]); std :: sort (__rank + 1, __rank + 1 + N); int Size = std :: unique (__rank + 1, __rank + 1 + N) - __rank - 1; President_Tree.Build (1, N); for (int i = 1; i <= N; i ++) { number[i] = std :: lower_bound (__rank + 1, __rank + 1 + Size, number[i]) - __rank; President_Tree.Updata (i, number[i]); } for (int x; M --; ) { read (x); printf ("%I64d\n", __rank[President_Tree.Query (x)]); } return 0; }
以上是关于2017.6.11 校内模拟赛的主要内容,如果未能解决你的问题,请参考以下文章