Berland Crossword(状压dp)

115 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Berland crossword is a puzzle that is solved on a square grid with nn rows and nn columns. Initially all the cells are white.

To solve the puzzle one has to color some cells on the border of the grid black in such a way that:

exactly U cells in the top row are black; exactly R cells in the rightmost column are black; exactly D cells in the bottom row are black; exactly L cells in the leftmost column are black. Note that you can color zero cells black and leave every cell white.

Your task is to check if there exists a solution to the given puzzle.

Input

The first line contains a single integer tt (1≤t≤1000) — the number of testcases.

Then the descriptions of tt testcases follow.

The only line of each testcase contains 5 integers n,U,R,D,L (2≤n≤100; 0≤U,R,D,L≤n).

Output

For each testcase print "YES" if the solution exists and "NO" otherwise.

You may print every letter in any case you want (so, for example, the strings yEs, yes, Yes and YES are all recognized as positive answer).

Example

input

4
5 2 5 3 1
3 0 0 0 0
4 4 1 4 0
2 1 1 1 1
output

YES
YES
NO
YES

翻译一下这道题吧:

横纵谜题是一个用n行n列的正方形网格来解决的谜题。最初所有的方格都是白色的。

为了破解谜题,我们必须把网格边界上的一些方格涂成黑色,如下所示:

  • 最上面一行的U个方格是黑色的;
  • 最右边一列的R个方格是黑色的;
  • 最下面一行的D个单元格是黑色的;
  • 最左边一列的L个单元格是黑色的。
  • 注意:你可以不把任意方格涂成黑色,让每个方格都是白色。

你的任务是检查是否存在一个方案解决给定的难题。

显然这道题目我们要关心的只有这个正方形网格的四个顶点处的格子是否被染色,由于只有四个格子,我们可以对其进行状压dp,那怎么判断是否合理呢?

设左上角,右上角,左下角,右下角的格子的状态分别为i,j,k,v,1代表染色,0代表未染色

以第一行为例来说吧,假如第一行要求格子有u个格子染色,那我们一定要保证i+j<=u,仅仅这一个条件就好了么?当然不是,我们要保证i+j<=u<=i+j+n-2,假如中间的格子都染色了加上两端的格子染色数目依旧没达到u个,那肯定是不符合题意的,其他行以及列同理,下面看代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
int n,u,r,d,l;
bool check(int i,int j,int k,int v)
{
//要保证第一行格子上染色的点数小于这一行要求的点数
//但要保证这一行除了拐角上的点之外的点全染色后的染色点数目大于要求的点数目 
//其他位置同理 
	if(i+j>u||n-2+i+j<u) return false;
	if(j+v>r||n-2+j+v<r) return false;
	if(k+v>d||n-2+k+v<d) return false;
	if(i+k>l||n-2+i+k<l) return false;
	return true;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n>>u>>r>>d>>l;
		bool flag=false;
		for(int i=0;i<=1;i++)
		for(int j=0;j<=1;j++)
		for(int k=0;k<=1;k++)
		for(int v=0;v<=1;v++)
			flag|=check(i,j,k,v);
		if(flag) puts("YES");
		else puts("NO");
	}
	return 0;
}