Codeforces-1234-C. Pipes(DFS)

C. Pipes

You are given a system of pipes. It consists of two rows, each row consists of n pipes. The top left pipe has the coordinates (1,1) and the bottom right — (2,n).

There are six types of pipes: two types of straight pipes and four types of curved pipes. Here are the examples of all six types:
Types of pipes

You can turn each of the given pipes 90 degrees clockwise or counterclockwise arbitrary (possibly, zero) number of times (so the types 1 and 2 can become each other and types 3,4,5,6 can become each other).

You want to turn some pipes in a way that the water flow can start at (1,0) (to the left of the top left pipe), move to the pipe at (1,1), flow somehow by connected pipes to the pipe at (2,n) and flow right to (2,n+1).

Pipes are connected if they are adjacent in the system and their ends are connected. Here are examples of connected pipes:
在这里插入图片描述

Examples of connected pipes

Let’s describe the problem using some example:

The first example input
在这里插入图片描述

And its solution is below:
在这里插入图片描述

The first example answer
As you can see, the water flow is the poorly drawn blue line. To obtain the answer, we need to turn the pipe at (1,2) 90 degrees clockwise, the pipe at (2,3) 90 degrees, the pipe at (1,6) 90 degrees, the pipe at (1,7) 180 degrees and the pipe at (2,7) 180 degrees. Then the flow of water can reach (2,n+1) from (1,0).

You have to answer q independent queries.

Input

The first line of the input contains one integer q (1≤q≤104) — the number of queries. Then q queries follow.

Each query consists of exactly three lines. The first line of the query contains one integer n (1≤n≤2⋅105) — the number of pipes in each row. The next two lines contain a description of the first and the second rows correspondingly. Each row description consists of n digits from 1 to 6 without any whitespaces between them, each digit corresponds to the type of pipe in the corresponding cell. See the problem statement to understand which digits correspond to which types of pipes.

It is guaranteed that the sum of n over all queries does not exceed 2⋅105.

Output

For the i-th query print the answer for it — “YES” (without quotes) if it is possible to turn some pipes in a way that the water flow can reach (2,n+1) from (1,0), and “NO” otherwise.

Example

input

6
7
2323216
1615124
1
3
4
2
13
24
2
12
34
3
536
345
2
46
54

output

YES
YES
YES
NO
YES
NO

Note

The first query from the example is described in the problem statement.

解题思路:

简单DFS,因为1,2管可以相互转化3,4,5,6可以相互转化因此就看成是两类管就好了便于处理。然后就是DFS的参数,需要本次的坐标以及上一次水流过来的坐标,以此来判断水的方向从而决定水的流向。

AC代码:

//#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <cstdlib>
#define read(x) scanf("%lld",&x)
#define re(n) for(int i = 0 ; i < n ; i ++)
#define rev(n) for(int i = n-1 ; i >= 0 ; i --)
#define fill(x,y) memset(x,y,sizeof(x))
const int N=1e6+10;
const int INF=0x3f3f3f3f;
typedef long long ll;
int a[2][N];
int mark[N];
ll n,m,i,j,k,t = 1;
int ans;
using namespace std;
 
void dfs(int x,int y,int x1,int y1)
{
    //cout<<x<<" "<<y<<" "<<x1<<" "<<y1<<endl;
    if(y == 1 && x == n)
    {
        ans = 1;
        return;
    }
    if(ans || y >= 2 || x >= n )
        return;
    if(y == y1) // 从左边来的水
    {
        if(a[y][x] == 1) // 横着的管
            dfs(x+1,y,x,y);
        else
        {
            if(y == 0)
                dfs(x,y+1,x,y);
            else
                dfs(x,y-1,x,y);
        }
    }
    else  // 从上边或者下边来的水
    {
        if(a[y][x] == 1) //横着的管,直接凉凉
            return;
        else    // 直角管可以往右边去
            dfs(x+1,y,x,y);
    }
}
 
int main()
{
    //freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    cin>>t;
    string s;
    for(int cas = 1 ; cas <= t ; cas ++)
    {
        cin>>n;
        cin>>s;
        re(n)
        {
            a[0][i] = s[i]-'0';
            if(a[0][i] == 2)
                a[0][i] = 1;
            if(a[0][i] > 2)
                a[0][i] = 2;
        }
        cin>>s;
        re(n)
        {
            a[1][i] = s[i]-'0';
            if(a[1][i] == 2)
                a[1][i] = 1;
            if(a[1][i] > 2)
                a[1][i] = 2;
        }
        ans = 0;
        dfs(0,0,-1,0);
        if(ans)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
        //cout<<"Case "<<cas<<":"<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]中提到了一种树形动态规划的方法来解决CodeForces - 982C问题。在这个问题中,subtree指的是子连通块,而不是子树。为了使cnt_white - cnt_black尽可能大,可以使用两次树形动态规划来求解。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。如果ans\[u\]为正,则减去dp\[v\]就是树链所代表的子树的权值。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] 问题: CodeForces - 982C 树形DP是什么问题?如何解决? 回答: CodeForces - 982C是一个树形动态规划问题。在这个问题中,需要求解子连通块的最大权值和,使得cnt_white - cnt_black尽可能大。解决这个问题的方法是使用两次树形动态规划。第一次是自底向上的过程,维护一个dp数组,表示以每个节点为根的子树中的最大连通块。第二次是自顶向下的过程,处理自底向上过程中无法包含的树链所代表的子树。在第二次遍历中,需要维护一个sum变量,用于存储树链所代表的子树的贡献。根据ans\[u\]的正负,决定是否能对相邻的子节点做出贡献。最终,ans\[u\]代表包含节点u在内的子连通块的最大权值。\[1\] #### 引用[.reference_title] - *1* *2* [CodeForces - 1324F Maximum White Subtree(树形dp)](https://blog.csdn.net/qq_45458915/article/details/104831678)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值