1. 程式人生 > 其它 >(模擬)Codeforces Round #699 (Div. 2) A ~ D 題

(模擬)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;
    }