(模拟)cf Codeforces Round #699 (Div. 2) A ~ D 题

https://codeforc.es/contest/1481
A. Space Navigation

You were dreaming that you are traveling to a planet named Planetforces on your personal spaceship. Unfortunately, its piloting system was corrupted and now you need to fix it in order to reach Planetforces.
在这里插入图片描述

Space can be represented as the XY plane. You are starting at point (0,0), and Planetforces is located in point (px,py).

The piloting system of your spaceship follows its list of orders which can be represented as a string s. The system reads s from left to right. Suppose you are at point (x,y) and current order is si:

  • if si=U, you move to (x,y+1);
  • if si=D, you move to (x,y−1);
  • if si=R, you move to (x+1,y);
  • if si=L, you move to (x−1,y).

Since string s could be corrupted, there is a possibility that you won’t reach Planetforces in the end. Fortunately, you can delete some orders from s but you can’t change their positions.

Can you delete several orders (possibly, zero) from s in such a way, that you’ll reach Planetforces after the system processes all orders?

Input

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

Each test case consists of two lines. The first line in each test case contains two integers px and py (−105≤px,py≤105; (px,py)≠(0,0)) — the coordinates of Planetforces (px,py).

The second line contains the string s(1≤|s|≤105: |s| is the length of string s) — the list of orders.

It is guaranteed that the sum of |s| over all test cases does not exceed 105.

Output

For each test case, print “YES” if you can delete several orders (possibly, zero) from s in such a way, that you’ll reach Planetforces. Otherwise, print “NO”. You can print each letter in any case (upper or lower).

Input

6
10 5
RRRRRRRRRRUUUUU
1 1
UDDDRLLL
-3 -5
LDLDLDDDR
1 2
LLLLUU
3 -2
RDULRLLDR
-1 6
RUDURUUUUR

Output

YES
YES
YES
NO
YES
NO

Note

In the first case, you don’t need to modify s, since the given s will bring you to Planetforces.

In the second case, you can delete orders s2, s3, s4, s6, s7 and s8, so s becomes equal to “UR”.

In the third test case, you have to delete order s9, otherwise, you won’t finish in the position of Planetforces.

题意:
给你一个目的地的坐标(px,py)和一些行动的命令,要求你可以删除一些命令(可以是0个)使得你能从(0,0)走到目的地(px,py)

思路:
统计每个方向的数量,如果可以到达那么就是这个方向的数量 >= px(或py)

代码:

    #include <bits/stdc++.h>
    #define DEBUG freopen("_in.txt", "r", stdin); freopen("_out1.txt", "w", stdout);
    #define CASE int t; cin >> t; while (t--)
    using namespace std;
    const int MAXC = 120;
    int a[MAXC];
    string dir;
    void solve(){
    
    
    	int x, y;
    	cin >> x >> y >> dir;
    	a['U'] = a['D'] = a['R'] = a['L'] = 0;
    	for (auto &ch : dir)
    		a[ch]++;
    	if (a['U'] >= y && -a['D'] <= y && a['R'] >= x && -a['L'] <= x)
    		cout << "YES" << endl;
    	else
    		cout << "NO" << endl;
    }
    int main(){
    
    
    	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    	CASE solve();
    	return 0;
    }

B. New Colony

After reaching your destination, you want to build a new colony on the new planet. Since this planet has many mountains and the colony must be built on a flat surface you decided to flatten the mountains using boulders (you are still dreaming so this makes sense to you).
在这里插入图片描述

You are given an array h1,h2,…,hn, where hi is the height of the i-th mountain, and k — the number of boulders you have.

You will start throwing boulders from the top of the first mountain one by one and they will roll as follows (let’s assume that the height of the current mountain is hi):

  • if hi≥hi+1, the boulder will roll to the next mountain;
  • if hi<hi+1, the boulder will stop rolling and increase the mountain
    height by 1 (hi=hi+1);
  • if the boulder reaches the last mountain it will fall to the waste
    collection system and disappear.

You want to find the position of the k-th boulder or determine that it will fall into the waste collection system.

Input

The first line contains a single integer t(1≤t≤100) — the number of test cases.

Each test case consists of two lines. The first line in each test case contains two integers n and k (1≤n≤100; 1≤k≤109) — the number of mountains and the number of boulders.

The second line contains n integers h1,h2,…,hn (1≤hi≤100) — the height of the mountains.

It is guaranteed that the sum of n over all test cases does not exceed 100.

Output

For each test case, print −1 if the k-th boulder will fall into the collection system. Otherwise, print the position of the k-th boulder.

Input

4
4 3
4 1 2 3
2 7
1 8
4 5
4 1 2 3
3 1
5 3 1

Output

2
1
-1
-1

Note

Let’s simulate the first case:

  • The first boulder starts at i=1; since h1≥h2 it rolls to i=2 and
    stops there because h2<h3.
  • The new heights are [4,2,2,3].
  • The second boulder starts at i=1; since h1≥h2 the boulder rolls to
    i=2; since h2≥h3 the boulder rolls to i=3 and stops there because
    h3<h4.
  • The new heights are [4,2,3,3].
  • The third boulder starts at i=1; since h1≥h2 it rolls to i=2 and
    stops there because h2<h3.
  • The new heights are [4,3,3,3].
  • The positions where each boulder stopped are the following: [2,3,2].

In the second case, all 7 boulders will stop right at the first mountain rising its height from 1 to 8.

The third case is similar to the first one but now you’ll throw 5 boulders. The first three will roll in the same way as in the first test case. After that, mountain heights will be equal to [4,3,3,3], that’s why the other two boulders will fall into the collection system.

In the fourth case, the first and only boulders will fall straight into the collection system.

题意:
有一个记录着不同的海拔高度的数组h [ ],要放 k 个石头,每个石头从i = 1处释放,用来填平数组h [ ],问最后一个石头的位置。

思路:
简单的模拟每一次放石头的过程。。。

代码:

    #include <bits/stdc++.h>
    #define DEBUG freopen("_in.txt", "r", stdin); freopen("_out1.txt", "w", stdout);
    #define CASE int t; cin >> t; while (t--)
    using namespace std;
    void solve(){
    
    
    	int n, k;
    	cin >> n >> k;
    	vector<int> h(n);
    	for (auto &v : h)
    		cin >> v;
    	while (k--){
    
    
    		int i;
    		for (i = 0; i < n - 1; i++)
    			if (h[i] < h[i+1])  //找到第一处凹起的位置
    				break;
    		if (i == n - 1){
    
      //到了最后的位置
    			cout << -1 << endl;
    			break;
    		}
    		if (k == 0){
    
    
    			cout << i+1 << endl;
    			break;
    		}
    		h[i]++;
    	}
    }
    int main(){
    
    
    	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    	CASE solve();
    	return 0;
    }

C. Fence Painting

You finally woke up after this crazy dream and decided to walk around to clear your head. Outside you saw your house’s fence — so plain and boring, that you’d like to repaint it.

在这里插入图片描述

You have a fence consisting of n planks, where the i-th plank has the color ai. You want to repaint the fence in such a way that the i-th plank has the color bi.

You’ve invited m painters for this purpose. The j-th painter will arrive at the moment j and will recolor exactly one plank to color cj. For each painter you can choose which plank to recolor, but you can’t turn them down, i. e. each painter has to color exactly one plank.

Can you get the coloring b you want? If it’s possible, print for each painter which plank he must paint.

Input

The first line contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.

The first line of each test case contains two integers n and m (1≤n,m≤105) — the number of planks in the fence and the number of painters.

The second line of each test case contains n integers a1,a2,…,an (1≤ai≤n) — the initial colors of the fence.

The third line of each test case contains n integers b1,b2,…,bn (1≤bi≤n) — the desired colors of the fence.

The fourth line of each test case contains m integers c1,c2,…,cm (1≤cj≤n) — the colors painters have.

It’s guaranteed that the sum of n doesn’t exceed 105 and the sum of m doesn’t exceed 105 over all test cases.

Output

For each test case, output “NO” if it is impossible to achieve the coloring b.

Otherwise, print “YES” and m integers x1,x2,…,xm, where xj is the index of plank the j-th painter should paint.

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).

Input

6
1 1
1
1
1
5 2
1 2 2 1 1
1 2 2 1 1
1 2
3 3
2 2 2
2 2 2
2 3 2
10 5
7 3 2 1 7 9 4 2 7 9
9 9 2 1 4 9 4 2 3 9
9 9 7 4 3
5 2
1 2 2 1 1
1 2 2 1 1
3 3
6 4
3 4 2 4 1 2
2 3 1 3 1 1
2 2 3 4

Output

YES
1
YES
2 2
YES
1 1 1
YES
2 1 9 5 9
NO
NO

题意:
有一个围栏有n 块木板:开始的时候每一块木板有一种颜色,有m 个油漆匠,按时间顺序可以把一块木板的颜色涂成自己油漆的颜色。最终要把围栏的每一块木板的颜色变成对应的颜色。可以的话输出每个油漆匠涂的木板位置,不可以的话输出NO。

思路:
倒序模拟每个油漆匠涂的过程(前面的油漆匠涂的木板颜色可以被后面油漆匠涂的木板颜色覆盖)。

代码:

    #include <bits/stdc++.h>
    #define DEBUG freopen("_in.txt", "r", stdin); freopen("_out1.txt", "w", stdout);
    #define CASE int t; cin >> t; while (t--)
    #define forcin(arr) for (auto &v : arr) cin >> v;
    using namespace std;
    void solve(){
    
    
    	int n, m, cnt = 0, diff = 0;  //cnt:木板颜色变换的个数,木板开始颜色与最终颜色不同的个数
    	int lastans = -1;  //记录最后的油漆匠涂的木板的位置
    	bool ac = true;
    	cin >> n >> m;
    	vector<int> f(n), w(n), work(m), ans(m);  //记录开始的颜色,最终的颜色,每个油漆匠的颜色,每个油漆匠涂木板的位置
    	vector<int> dif[n+1], same(n+1);  //记录每个木板开始颜色与最终颜色不同/相同的位置
    	forcin(f);
    	forcin(w);
    	forcin(work);
    	for (int i = 0; i < n; i++)
    		if (w[i] == f[i])
    			same[w[i]] = i + 1;
    		else{
    
    
    			dif[w[i]].push_back(i+1);
    			diff++;
    		}
    	for (int i = m - 1, Size; i >= 0; i--){
    
      //倒序模拟
    		Size = dif[work[i]].size();
    		if (Size == 0){
    
    
    			if (lastans == -1){
    
    
    				if (same[work[i]] == 0){
    
       //每个木板最终的颜色中没有这个油漆匠的颜色
    					ac = false;
    					break;
    				}
    				ans[i] = same[work[i]];
    				lastans = ans[i];
    			}
    			else
    				ans[i] = lastans;
    		}
    		else{
    
    
    			ans[i] = dif[work[i]].at(Size-1);
    			dif[work[i]].pop_back();
    			cnt++;
    			if (lastans == -1)
    				lastans = ans[i];
    		}
    	}
    	if (ac && cnt >= diff){
    
    
    		cout << "YES\n" << ans[0];
    		for (int i = 1; i < m; i++)
    			cout << ' ' << ans[i];
    		cout << endl;
    	}
    	else
    		cout << "NO" << endl;
    }
    int main(){
    
    
    	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    	CASE solve();
    	return 0;
    }

D. AB Graph

Your friend Salem is Warawreh’s brother and only loves math and geometry problems. He has solved plenty of such problems, but according to Warawreh, in order to graduate from university he has to solve more graph problems. Since Salem is not good with graphs he asked your help with the following problem.

在这里插入图片描述

You are given a complete directed graph with n vertices without self-loops. In other words, you have n vertices and each pair of vertices u and v (u≠v) has both directed edges (u,v) and (v,u).

Every directed edge of the graph is labeled with a single character: either ‘a’ or ‘b’ (edges (u,v) and (v,u) may have different labels).

You are also given an integer m>0. You should find a path of length m such that the string obtained by writing out edges’ labels when going along the path is a palindrome. The length of the path is the number of edges in it.

You can visit the same vertex and the same directed edge any number of times.

Input

The first line contains a single integer t (1≤t≤500) — the number of test cases.

The first line of each test case contains two integers n and m (2≤n≤1000; 1≤m≤105) — the number of vertices in the graph and desirable length of the palindrome.

Each of the next n lines contains n characters. The j-th character of the i-th line describes the character on the edge that is going from node i to node j.

Every character is either ‘a’ or ‘b’ if i≠j, or ‘*’ if i=j, since the graph doesn’t contain self-loops.

It’s guaranteed that the sum of n over test cases doesn’t exceed 1000 and the sum of m doesn’t exceed 105.

Output

For each test case, if it is possible to find such path, print “YES” and the path itself as a sequence of m+1 integers: indices of vertices in the path in the appropriate order. If there are several valid paths, print any of them.

Otherwise, (if there is no answer) print “NO”.

Input

5
3 1
*ba
b*b
ab*
3 3
*ba
b*b
ab*
3 4
*ba
b*b
ab*
4 6
*aaa
b*ba
ab*a
bba*
2 6
*a
b*

Output

YES
1 2
YES
2 1 3 2
YES
1 3 1 3 1
YES
1 2 1 3 4 1 4
NO

Note

The graph from the first three test cases is shown below:

在这里插入图片描述

In the first test case, the answer sequence is [1,2] which means that the path is:

在这里插入图片描述
So the string that is obtained by the given path is b.

In the second test case, the answer sequence is [2,1,3,2] which means that the path is:

在这里插入图片描述

So the string that is obtained by the given path is bab.

In the third test case, the answer sequence is [1,3,1,3,1] which means that the path is:

在这里插入图片描述

So the string that is obtained by the given path is aaaa.

The string obtained in the fourth test case is abaaba.

题意:
给你一张图,每条路都有一个字母a 或字母 b,要求你在m 步找到一个回文串路径(每个顶点每条路可以重复走)。

思路:
如果两个顶点的路的字母相同,则可以重复的走这两个顶点;
如果没有这样特殊的顶点的话,则每个顶点当作最开始的点 dfs 模拟一下。举个例子:
在这里插入图片描述
其中一个回文串:abba,路径:1 → 2 → 3 → 1 → 2

代码

    #include <bits/stdc++.h>
    #define DEBUG freopen("_in.txt", "r", stdin); freopen("_out1.txt", "w", stdout);
    #define CASE int t; cin >> t; while (t--)
    #define CASEE int t; cin >> t; for (int ti = 1; ti <= t; ti++)
    #define forcin(arr) for (auto &v : arr) cin >> v;
    #define forcout(arr) for (auto &v : arr) cout << v << ' '; cout << endl; 
    using namespace std;
    const int MAXN = 1010;
    const int MAXM = 1e5 + 10;
    int ans[MAXM];  //回文串的路径
    char a[MAXN][MAXN], dir[MAXM];  //a:邻接矩阵存储图,dir:回文串
    bool ac;
    void printans(int a, int b, int t){
    
      //特殊情况的打印
    	int ti = t >> 1;
    	cout << "YES" << endl;
    	while (ti--)
    		cout << a << ' ' << b << ' ';
    	if (t & 1)
    		cout << a;
    	cout << endl;
    }
    void dfs(int idx, int n, int m, int mid, int steps){
    
    
    	if (steps == m){
    
    
    		ac = true;
    		return;
    	}
    	for (int i = 0; i < n; i++){
    
    
    		if (i == idx)  //没有环
    			continue;
    		if (mid <= steps && a[idx][i] != dir[m-1-steps])  //路径不是回文串
    			continue;
    		if (mid > steps)  //记录路径的回文
    			dir[steps] = a[idx][i];
    		ans[steps] = i;  //记录路径
    		dfs(i, n, m, mid, steps+1);
    		if (ac)
    			break;
    	}
    }
    void solve(){
    
    
    	int n, m, mid;
    	cin >> n >> m;
    	mid = m >> 1;
    	if (m & 1)
    		mid++;
    	for (int i = 0; i < n; i++)
    		cin >> a[i];
    	if (m == 1){
    
    
    		cout << "YES\n1 2" << endl;
    		return;
    	}
    	for (int i = 0; i < n; i++)
    		for (int j = i + 1; j < n; j++)
    			if (a[i][j] == a[j][i]){
    
      //两个顶点的路的字母相同,则可以重复的走这两个顶点
    				printans(i+1, j+1, m+1);
    				return;
    			}
    	for (int i = 0; i < n; i++){
    
      //遍历每个顶点
    		ac = false;
    		dfs(i, n, m, mid, 0);
    		if (ac){
    
    
    			cout << "YES\n" << i+1;
    			for (int i = 0; i < m; i++)
    				cout << ' ' << ans[i]+1;
    			cout << endl;
    			return;
    		}
    	}
    	cout << "NO" << endl;
    }
    int main(){
    
    
    	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    	CASE solve();
    	return 0;
    }

猜你喜欢

转载自blog.csdn.net/ymxyld/article/details/113719488
今日推荐