HUST 1525

Given an N*N(N<=1000)chessboard where you want to place chess knights.
On this chessboard you have to apply M(M<=100000) operations:
Input
The first line contains a single integer T, the number of test cases.
For each case,
The first line contains integer N, M.
The next M lines contain the operation in following form.
C a b x: place chess knight on cell(a,b), the value of the knight is x. (1<=a,b<=n, 1<=x<=100000)
It grants that cell(a,b) has no knight before the operation.
Q a b: answer the maximum value of knight which is connected with knight(a,b), include itself.
If cell (a,b)has no knight, just answer -1. A knight is directly connected with the knight on the left,
right, up and down. Two knights are connected if they have been directly connected or
interconnected through some other connected knights.
The initial chessboard is empty.
Output
For each question, output the answer in one line.
Sample Input
1
3 7
C 2 2 1
Q 2 2
C 1 2 2
Q 2 2
C 3 3 3
Q 3 3
Q 1 1
Sample Output
1
2
3

-1


题意就是找图中连通块的最大值,并查集解决就可以了,将二维映射到一维,题目并不难,恶心的是题目中明明说明x>=1,但是却存在了为1的数,最开始我将图中所有的值初始化为0,一直wrong answer,后来队友帮忙调试,首先修改了我的输入,我原来的输入是scanf("%*c%c%d%d",&cmd,&x,&y); 后来证明这种写法确实和编译器有关系,hust上跑不过,以后不再使用这种写法了,其次就是图不能初始化为0,要赋值为-1;对hust无爱了。

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

const int maxn=2050;
int mp[maxn*maxn];
int n,m;
int uset[maxn*maxn];

int Find(int x)
{
    if(x==uset[x]) return x;
    return uset[x]=Find(uset[x]);
}
bool check(int x,int y)
{
    if(x>=1 && x<=n && y>=1 && y<=n && mp[Find((x-1)*n+y)]!=-1) return true;
    return false;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(mp,-1,sizeof(mp));
        for(int i=0; i<maxn*maxn; i++)
            uset[i]=i;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=m; i++)
        {
            char cmd;
            int x,y,v;
            scanf(" %c%d%d",&cmd,&x,&y);
            if(cmd=='C')
            {
                scanf("%d",&v);
                int pos=(x-1)*n+y;
                mp[pos]=v;
                if(check(x,y-1))
                {
                    int u=Find(pos);
                    int v=Find(pos-1);
                    if(mp[u]>=mp[v])
                        uset[v]=u;
                    else
                        uset[u]=v;
                }
                if(check(x,y+1))
                {
                    int u=Find(pos);
                    int v=Find(pos+1);
                    if(mp[u]>=mp[v])
                        uset[v]=u;
                    else
                        uset[u]=v;
                }
                if(check(x-1,y))
                {
                    int u=Find(pos);
                    int v=Find(pos-n);
                    if(mp[u]>=mp[v])
                        uset[v]=u;
                    else
                        uset[u]=v;
                }
                if(check(x+1,y))
                {
                    int u=Find(pos);
                    int v=Find(pos+n);
                    if(mp[u]>=mp[v])
                        uset[v]=u;
                    else
                        uset[u]=v;
                }
            }
            else if(cmd=='Q')
            {
                int pos=(x-1)*n+y;
                if(mp[pos]==-1)
                    printf("-1\n");
                else
                {
                    printf("%d\n",mp[Find(pos)]);
                }
            }
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值