Codeforces Round #480 (Div. 2) B. Marlin

B. Marlin

The city of Fishtopia can be imagined as a grid of 44 rows and an odd number of columns. It has two main villages; the first is located at the top-left cell (1,1)(1,1), people who stay there love fishing at the Tuna pond at the bottom-right cell (4,n)(4,n). The second village is located at (4,1)(4,1) and its people love the Salmon pond at (1,n)(1,n).

The mayor of Fishtopia wants to place kk hotels in the city, each one occupying one cell. To allow people to enter the city from anywhere, hotels should not be placed on the border cells.

A person can move from one cell to another if those cells are not occupied by hotels and share a side.

Can you help the mayor place the hotels in a way such that there are equal number of shortest paths from each village to its preferred pond?

Input

The first line of input contain two integers, nn and kk (3n993≤n≤990k2×(n2)0≤k≤2×(n−2)), nn is odd, the width of the city, and the number of hotels to be placed, respectively.

Output

Print "YES", if it is possible to place all the hotels in a way that satisfies the problem statement, otherwise print "NO".

If it is possible, print an extra 44 lines that describe the city, each line should have nn characters, each of which is "#" if that cell has a hotel on it, or "." if not.

Examples
input
Copy
7 2
output
Copy
YES
.......
.#.....
.#.....
.......
input
Copy
5 3
output
Copy
YES
.....
.###.
.....
.....

题意:现在有一个4*n的矩形地图,左上角是村子,要去右下角打水,左下角也是村子,要去右上角打水,现在要造k个旅馆,人就不能走旅馆的位置了,说白了旅馆就是障碍物,问你怎么放旅馆能让两个村子打水时最短路的条数相等,矩形周围一圈不能放,即第一行,第四行,第一列,第n列不可以放旅馆。

思路:其实就是保证两个村子打水路程平等,不绕远路,可以看到数据范围k<=2*(n-2),

即旅馆个数最多填满2,3两行。

1.当k为偶数时,竖着从左到右填2,3两行即可,必然是YES。

2.当k为奇数时,我们先填第二行,保证左右对称即可满足题意,所以从中间往两边扩展。如果第二行填满还有剩余,此时填第三行,由于n保证是奇数,所以第二行填满后剩余k必然是偶数,此时第三行要想保证对称,必须从两边往中间填,自己画一下就很好理解了。

一共就这两种情况,输出必然是YES,想清楚了其实就是模拟。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define exp 1e-8
#define mst(a,k) memset(a,k,sizeof(a))
using namespace std;
ll n,k;
int main()
{
    while(~scanf("%lld%lld",&n,&k))
    {
        if(k%2==0)
        {
            printf("YES\n");
            for(ll i=1;i<=n;i++)printf(".");
            printf("\n");
            ll p1=k/2,p2=k/2;
            for(ll i=1;i<=n;i++)   //直接竖着两个两个填即可
            {
                if((i!=1)&&(i!=n)&&(p1))
                {
                    printf("#");
                    p1--;
                }
                else printf(".");
            }
            printf("\n");
            for(ll i=1;i<=n;i++)
            {
                if((i!=1)&&(i!=n)&&(p2))
                {
                    printf("#");
                    p2--;
                }
                else printf(".");
            }
            printf("\n");
            for(ll i=1;i<=n;i++)printf(".");
            printf("\n");
        }
        else
        {
            printf("YES\n");
            for(ll i=1;i<=n;i++)printf(".");
            printf("\n");
            ll vis[110];
            mst(vis,0);
            ll l=n/2+1,r=n/2+1;
            while(1)   //从中间往两边
            {
                if(k)
                {
                    vis[l]=vis[r]=1;
                    if(l!=r)k-=2;
                    else k--;
                }
                else break;
                l--;
                r++;
                if(l==1)break;
            }
            for(ll i=1;i<=n;i++)
            {
                if(vis[i])printf("#");
                else printf(".");
            }
            printf("\n");
            l=2,r=n-1;
            mst(vis,0);
            while(l<r)   //从两边往中间
            {
                if(k)
                {
                    vis[l]=vis[r]=1;
                    k-=2;
                }
                else break;
                l++;
                r--;
            }
            for(ll i=1;i<=n;i++)
            {
                if(vis[i])printf("#");
                else printf(".");
            }
            printf("\n");
            for(ll i=1;i<=n;i++)printf(".");
            printf("\n");
        }
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值