牛客网暑期ACM多校训练营(第二场) I Car 思维

链接:https://www.nowcoder.com/acm/contest/140/I
来源:牛客网

White Cloud has a square of n*n from (1,1) to (n,n).
White Rabbit wants to put in several cars. Each car will start moving at the same time and move from one side of one row or one line to the other. All cars have the same speed. If two cars arrive at the same time and the same position in a grid or meet in a straight line, both cars will be damaged.
White Cloud will destroy the square m times. In each step White Cloud will destroy one grid of the square(It will break all m grids before cars start).Any car will break when it enters a damaged grid.
White Rabbit wants to know the maximum number of cars that can be put into to ensure that there is a way that allows all cars to perform their entire journey without damage.
(update: all cars should start at the edge of the square and go towards another side, cars which start at the corner can choose either of the two directions)

For example, in a 5*5 square


legal

illegal(These two cars will collide at (4,4))


illegal (One car will go into a damaged grid)

输入描述:

The first line of input contains two integers n and m(n <= 100000,m <= 100000)
For the next m lines,each line contains two integers x,y(1 <= x,y <= n), denoting the grid which is damaged by White Cloud.

输出描述:

Print a number,denoting the maximum number of cars White Rabbit can put into.

示例1

输入

复制
2 0

输出

复制
4

备注:

分析:首先看没有陷阱的时候,n*n最多可以在边界上放几辆车,然后再思考加每个陷阱被影响到的行和列。

通过爆搜或者手写所有情况找规律,我们很容易得出n*n的时候边界放的车的奇数的情况为:(n/2)*4+1,偶数的情况为:2*n

每次加陷阱会影响到陷阱所在的行和列,我们分别用两个vis数组保存起来被影响到的行和列。

首先看n为偶数

图为n是偶数的时候,此时n为4,最多可以放车子八辆,八辆车的情况我们可以变成图中这种情况(比如(2,2)我可以直接横移到(2,1)边界处就满足了条件)

然后我们可以发现陷阱处于此图中任何位置都会影响到两辆车,所以n为偶数时候陷阱的位置行和列都将受到影响,我们记录下来就好

接着是n为奇数

图为n为5的时候,最多可以放九辆车,如上面一样可以画成这样的形式。然后我们很容易看出来除了陷阱位于中心点,在其他点都可以影响到两辆车,中心点影响到一辆车。

下面是我的实现代码

#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define debug(a) cout << #a << " " << a << endl
using namespace std;
const int maxn = 1e6 + 10;
const int mod = 10000007;
typedef long long ll;
int vis1[maxn], vis2[maxn] ;
struct node{
     int x, y ;
}e[maxn];
int n , m ;
int main(){
    while( scanf("%d %d",&n,&m) != EOF) {
        memset(vis1,0,sizeof(vis1)) ;
        memset(vis2,0,sizeof(vis2)) ;
        long long int sum = n%2 == 0 ? 2*n : (n/2)*4 + 1 ;
        for( int i = 1 ; i <= m ; i ++ ){
            scanf("%d %d",&e[i].x,&e[i].y) ;
            vis1[e[i].x] = 1 ; vis2[e[i].y] = 1 ;
        }
        long long ans = 0 ;
        for(int i = 1 ; i <= n ; i ++) {
            if(vis1[i]) ans ++ ;
            if(vis2[i]) ans ++ ;
        }
        if( n%2 && ( vis1[(n + 1)/2] || vis2[(n + 1)/2] ) ) {
            ans -- ;
        }
        printf("%lld\n",sum - ans) ;
    }
    return 0 ;
}

  

posted on 2018-07-21 20:32  九月旧约  阅读(212)  评论(0编辑  收藏  举报

导航