CodeForces - 200ACinema模拟题

CodeForces - 200A

Cinema

Time Limit: 1500MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u

Submit Status

Description

The capital of Berland has the only movie theater in the country. Besides, it consists of only one room. The room is divided into n rows, each row consists of m seats.

There are k people lined up to the box office, each person wants to buy exactly one ticket for his own entertainment. Before the box office started selling tickets, each person found the seat
that seemed best for him and remembered it as a pair of coordinates (xi,?yi), where xi is
the row number, and yi is the seat number in this row.

It is possible that some people have chosen the same place, then when some people see their favorite seat taken in the plan of empty seats in the theater, they choose and buy a ticket to another place. Each of them has the following logic: let‘s assume that
he originally wanted to buy a ticket to seat (x1,?y1), then when he comes to the box office, he chooses such empty seat (x2,?y2),
which satisfies the following conditions:

  • the value of |x1?-?x2|?+?|y1?-?y2| is
    minimum
  • if the choice is not unique, then among the seats that satisfy the first condition, this person selects the one for which the value of x2 is minimum
  • if the choice is still not unique, among the seats that satisfy the first and second conditions, this person selects the one for which the value of y2 is minimum

Your task is to find the coordinates of a seat for each person.

Input

The first input line contains three integers nmk (1?≤?n,?m?≤?2000, 1?≤?k?≤?min(n·m,?105)
— the number of rows in the room, the number of seats in each row and the number of people in the line, correspondingly. Each of the next k lines contains two integers xiyi (1?≤?xi?≤?n, 1?≤?yi?≤?m)
— the coordinates of the seat each person has chosen. Numbers on the same line are separated by a space. The pairs of coordinates are located in the order, in which people stand in the line, starting from the head (the first person in the line who stands in
front of the box office) to the tail (the last person in the line).

Output

Print k lines, each containing a pair of integers. Print on the i-th line xi,?yi —
the coordinates of the seat, for which the person who stands i-th in the line will buy the ticket.

Sample Input

Input

3 4 6
1 1
1 1
1 1
1 2
1 3
1 3

Output

1 1
1 2
2 1
1 3
1 4
2 3

Input

4 3 12
2 2
2 2
2 2
2 2
2 2
2 2
2 2
2 2
2 2
2 2
2 2
2 2

Output

2 2
1 2
2 1
2 3
3 2
1 1
1 3
3 1
3 3
4 2
4 1
4 3
 |x1-x2|+|y1-y2| 大家可以理解为横着走多少步,竖着走多少步,加起来就是它的值,现在主要思维是,从一个点开始选择,可能相同的路径已经进行过一次,为了防止超时,我们最主要的工作是减少相同路径重复走几次,如此通过一个d[x][y]表示这个点周围已经走了多少次这里我们要考虑一个情况,就是包围情况,如果一个点的位置在另一个点选择的时候就已经访问了,那么我们就要通过另一个点更新该点
现在讲解这份代码的含义:
for(int i=-1; i<=1; i++) {
            for(int j=-1; j<=1; j++) {
                if(x+i<=0||y+j<=0||x+i>=n||y+j>=m)continue;
                d[x][y]=max(d[x][y],d[x+i][y+j]-abs(i)-abs(j));
        }
}
d[x][y]之前已经说明了,代表着从这个点开始周围的d-1步内都已经被人给选择,不是空位置那么对于d[x][y]与d[x+i][y+j],大家可以画个图,或者是在脑海里思考一下


如果d[x+i][y+j]为零的,证明d[x][y]与d[x+i][y+j]是没有交集如此得到的肯定还是d[x][y]
因为d[x+i][y+j]-abs(i)-abs(j),这个代表着(x+i,y+j)这个点到(x,y)的距离,这个式子肯定小于零
接着我们思考如果d[x+i][y+j]从(x+i,y+j)这个点开始周围的d-1步内都已经被人给选择,且(x,y)这个点也包括在d-1步内,那么我们可以思考一下,如果这个点已经被访问了,那么可不可以通过其他点的d值得到我这个点最小应该走多少步的d值呢,答案是肯定的,因为如果d[x+i][d+j]步内包括有(x,y)这个点被访问,那么这个点的d[x+i][y+j]值减去abs(i)+abs(j)的值就是他(x,y)周围已经访问了点的最大半径

如此取所有情况的最大值,这里i与j的范围可以自行拟定,因为通过上述说明他的值可以取符合条件的任何值,但是出于时间复杂度的考虑大家可以选择(-1,1),或者是(-2,2),或者是(-3,3)皆可。
代码呈上:
/*
Author: 2486
Memory: 19488 KB		Time: 795 MS
Language: GNU G++ 4.9.2		Result: Accepted
*/

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=2000+5;
bool vis[maxn][maxn];
int d[maxn][maxn];
int n,m,k,ex,ey;
//这个函数的功能是将d转换为行列进行检查,代码大家都懂
bool Check(int x,int y) {
    int l=max(x-d[x][y],1),r=min(x+d[x][y],n);
    for(int i=l; i<=r; i++) {
        int t=d[x][y]-abs(i-x);
        if(y-t>0&&!vis[i][y-t]) {
            ex=i;
            ey=y-t;
            return false;
        }
        if(y+t<=m&&!vis[i][y+t]) {
            ex=i;
            ey=y+t;
            return false;
        }
    }
    return true;
}
int main() {
    //freopen("D://imput.txt","r",stdin);
    int x,y;
    scanf("%d%d%d",&n,&m,&k);
    for(int f=0; f<k; f++) {
        scanf("%d%d",&x,&y);
        if(!vis[x][y]) {
            printf("%d %d\n",x,y);
            vis[x][y]=true;
            continue;
        }
        for(int i=-1; i<=1; i++) {
            for(int j=-1; j<=1; j++) {
                if(x+i<=0||y+j<=0||x+i>=n||y+j>=m)continue;
                d[x][y]=max(d[x][y],d[x+i][y+j]-abs(i)-abs(j));
            }
        }
        while(Check(x,y)) {//接着一步一步往外扩展
            d[x][y]++;
        }
        vis[ex][ey]=true;
        printf("%d %d\n",ex,ey);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-17 07:09:16

CodeForces - 200ACinema模拟题的相关文章

CodeForces - 427B (模拟题)

Prison Transfer Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status Description The prison of your city has n prisoners. As the prison can't accommodate all of them, the city mayor has decided to transfer c of t

CodeForces - 404B(模拟题)

Marathon Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status Description Valera takes part in the Berland Marathon. The marathon race starts at the stadium that can be represented on the plane as a square whose

CodeForces - 404A(模拟题)

Valera and X Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status Description Valera is a little boy. Yesterday he got a huge Math hometask at school, so Valera didn't have enough time to properly learn the Engli

Codeforces 48C The Race 模拟题

题目链接:点击打开链接 题意: 给定n个加油站,一辆车由A点跑到B点,每个100m有一个加油站,每开100m需要10升油. 在每个车站会检查一下油量,若车子若开不到下一个加油站则加x升油. 开始有x升油 下面给出加油的记录. 问下一次加油在哪一站.若答案唯一输出具体哪站. 油箱容量无限 思路: 水模拟.. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h>

HDU 4028 The time of a day STL 模拟题

暴力出奇迹.. #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define ll __int64 #define N 42 ll n,m,ans;

cf428c 模拟题

这题说的是给了 n个数然后又 k次 的交换任意位置的 数字的机会  计算最长的连续子序列的和 这要撸  模拟整个 过程 并不能就是算最长的递增序列 如果只是 找最长的 和序列的 话 会存在 很多问题 在替换的时候 每一个决策 都影响着 下一个决策  这样 存在谁与谁替换 这样的状态有 200!种    那就枚举每个区间这样就可以使得 我们所用替换方法得当  因为在替换中我们进行替换是对不同区间的 操作 比如 在替换序列之内的 数字的时候 其实操作的就是不同的区间 与外面的序列进行替换的时候 操作

TOJ1290 Poker Hands 模拟题

寒假期间抽空做的一道模拟题 难度不算大,把每种牌型分开处理,可以合并的步骤考虑合并. 代码比较丑陋,首次尝试Sport Programming的风格,结果搞了个不伦不类(手动笑哭) 1 #include <algorithm> 2 #include <bitset> 3 #include <cctype> 4 #include <complex> 5 #include <cstdio> 6 #include <cstring> 7 #

hdu 5641 King&#39;s Phone(暴力模拟题)

Problem Description In a military parade, the King sees lots of new things, including an Andriod Phone. He becomes interested in the pattern lock screen. The pattern interface is a 3×3 square lattice, the three points in the first line are labeled as

HDU 2414 Chessboard Dance(模拟题,仅此纪念我的堕落)

题目 模拟题也各种wa,我最近真的堕落了,,,,,智商越来越为负数了!!!!!!!! #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; char mp[10][10]; int d=-1;//0shang,1xia,2zuo,3you int x,y;//weizhi int weizhi(int i,int j) { if(mp[i][j]=='<'){x=