HUST 1625 Chessboard

来源:互联网 发布:自己怎么开淘宝直播间 编辑:程序博客网 时间:2024/04/29 14:52

Chessboard

Time Limit: 1 Sec  Memory Limit: 128 MB
Submissions: 39  Solved: 11

Description

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

13 7C 2 2 1Q 2 2C 1 2 2Q 2 2C 3 3 3Q 3 3Q 1 1

Sample Output

123-1

HINT

Source

The 8th(2013) ACM Programming Contest of HUST


#include<iostream>#include<stdio.h>using namespace std;#define maxn 1001int d[4][2]={0,-1,0,1,-1,0,1,0};bool num[maxn][maxn];int N;struct node{    int parent;    int value;}elem[maxn*maxn];void init(){    for(int i=0;i<N;i++)        for(int j=0;j<N;j++)        {            elem[i*N+j].value=0;            elem[i*N+j].parent=i*N+j;            num[i] [j] =0;        }}int Find(int m){    if(elem[m] .parent!=m) return elem[m] .parent=Find(elem[m] .parent);    return m;/*    int root,temp;    temp=m;    while(m!=elem[m] .parent)        m=elem[m] .parent;    root=m;    m=temp;    while(m!=elem[m] .parent)    {        temp=elem[m] .parent;        elem[m] .parent=root;        m=temp;    }    return root;*/}void Union(int ax,int bx){    int a,b;    a=Find(ax);    b=Find(bx);    if(elem[a] .value>=elem[b] .value)    {        elem[b] .parent=elem[a] .parent;        //elem[b] .value+=elem[a] .value;    }    else    {        elem[a] .parent=elem[b] .parent;//elem[a] .value+=elem[b] .value;    }}void cutin(int x,int y,int n){    elem[x*N+y].value=n;    num[x] [y] =1;}int main(){    int T,M;    char c[2];    int x,y,n;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&N,&M);        //cin>>N>>M;        init();        for(int i=0;i<M;i++)        {            scanf("%s",c);            if(c[0]=='Q')            {                scanf("%d%d",&x,&y);                //   cin>>x>>y;                x-=1;                y-=1;                if(num[x] [y] ==0) printf("-1\n");                else                {                    int ans=Find(x*N+y);                    printf("%d\n",elem[ans] .value);                    // cout<<elem[ans] .value<<endl;                }            }            else if(c[0]=='C')            {                scanf("%d%d%d",&x,&y,&n);                // cin>>x>>y>>n;                x-=1;y-=1;                cutin(x,y,n);                for(int i=0;i<4;i++)                {                    int dx=d[i] [0];                    int dy=d[i] [1];                    int nx=x+dx;                    int ny=y+dy;                    if(0<=nx&&nx<N&&0<=ny&&ny<N&&num[nx] [ny] !=0)                    {                        int ax=x*N+y;                        int bx=nx*N+ny;                        Union(ax,bx);                    }                }            }        }    }    return 0;}

方法:

建立一个bool 类型的二维数组 记录 位置是否有数

一个一维数组存并查集 原坐标(i,j),新坐标i*n+j

并查集的模板


第一次写并查集。问了好多的人。最后自己写的TLE了。

问题:

1.数组开小了 之前是maxn<<4 后来改成了maxn*maxn

2.输入输出从c++改成了c  注意的地方是 读char的时候 要设成string类型 不然之前的回车和空格可能会被吃掉

3.find函数改成了递归函数


前两个问题当时写线段树的时候就经常的出现,自己还是没能发现和克服。

最后一个就有点智商捉急了。


感谢死命催了我两天的小伙伴,给了关键思路的小伙伴,最后把程序改正确的小伙伴。

虽然还是很遗憾,没能自己把程序调AC,这个假期的基本目标就是可以自己独立的调试程序。

做题的感觉不错。

0 0
原创粉丝点击