首页 > 代码库 > 2017.6.11 校内模拟赛

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 校内模拟赛