HDU 4941

昨天做的多校题目。
题目大概就是说有n*m的一个方格,其中k个格子里放了数字。然后进行q个操作,1是交换列,2是交换行,3是查询当前x,y有什么数字,没有输出0。

题目不难,但是写起来有点别扭。主要的思想是hash。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define maxn 100010

struct N
{
    int x, y, val;
} node[maxn];

int x[maxn], y[maxn];
int xx[maxn], yy[maxn];
int changex[maxn], changey[maxn];
int n, m, k;

void solve1()
{
    int q;
    cin >> q;
    while(q--)
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        if(a == 3)
        puts("0");
    }
    return ;
}

int find(int qq[], int q, int tk)
{
   // for(int i = 0; i < tk; i ++)
   // cout << qq[i] << endl;
    int l = lower_bound(qq, qq+tk, q) - qq;
    int r = upper_bound(qq, qq+tk, q) - qq;
   // cout << qq[l] << " " << qq[r] << " " << q << endl;
     if(l > r)
        return -1;
    if(l == r-1)
    return l;
    else
    while(1) l++;
}

int solve(int qx, int qy)
{
    qx = changex[qx];
    qy = changey[qy];
    int l = lower_bound(x, x+k, xx[qx]) - x;
    int r = upper_bound(x, x+k, xx[qx]) - x;
    r--;

    qy = yy[qy];
    while(l <= r)
    {
        int m = (l + r) / 2;
        if(node[m].y > qy)
        r = m-1;
        else if(node[m].y < qy)
        l = m+1;
        else
        return node[m].val;
    }
    return 0;
}

bool cmp(N a, N b)
{
    if(a.x == b.x)
        return a.y < b.y;
    return a.x < b.x;
}

int main()
{
   // f//reopen("in.txt", "r", stdin);
    //freopen("out(2).txt", "w", stdout);
    int t;
    cin >> t;
    for(int Ca = 1; Ca <= t; Ca++)
    {
        scanf("%d%d%d", &n, &m, &k);
        for(int i = 0; i < k; i++)
        {
            scanf("%d%d%d", &node[i].x, &node[i].y, &node[i].val);
            x[i] = node[i].x;
            y[i] = node[i].y;
        }
        printf("Case #%d:
", Ca);
        sort(node, node + k, cmp);
        sort(x, x + k);
        sort(y, y + k);
        if(!k)
        {
            solve1();
            continue;
        }
        xx[0] = x[0];
        int sumx = 1;
        for(int i = 1; i < k; i++)
            if(x[i] != x[i-1])
                xx[sumx++] = x[i];

        yy[0] =y[0];
        int sumy = 1;
        for(int i = 1; i < k; i++)
            if(y[i] != y[i-1])
                yy[sumy++] = y[i];


        for(int i = 0; i < sumx; i++)
            changex[i] = i;
        for(int i = 0; i < sumy; i++)
            changey[i] = i;

        int q;
        cin >> q;
        while(q--)
        {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
                            //cout << a << " " << b << " " << c << endl;
            if(a == 2)
            {
                b = find(yy, b, sumy);
                c = find(yy, c, sumy);
                 if(b == -1 && c == -1)
                continue;
                swap(changey[b], changey[c]);
            }
            else if(a == 1)
            {
                b = find(xx, b, sumx);
                c = find(xx, c, sumx);
                //cout << a << " " << b << " " << c << endl;
                if(b == -1 && c == -1)
                continue;
                 swap(changex[b], changex[c]);
            }

            else
            {
                b = find(xx, b, sumx);
                c = find(yy, c, sumy);
                if(b == -1 || c == -1)
                puts("0");
                else
                printf("%d
", solve(b, c));
            }

        }
    }
}
View Code

开始的时候WA了几发,因为upper_bound(), 返回的是大于键值的第一个位置,我以为是小于等于键值的第一个位置。。。
真心跪了,我这基础是有多不扎实啊。

原文地址:https://www.cnblogs.com/ye8370/p/3909202.html