2022-03-10每日刷题打卡

147 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

2022-03-10每日刷题打卡

力扣——每日一题

589. N 叉树的前序遍历

给定一个 n 叉树的根节点 root ,返回 其节点值的 前序遍历 。

n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)。

示例 1:

narytreeexample.png (781×502) (leetcode.com)

输入:root = [1,null,3,2,4,null,5,6]
输出:[1,3,5,6,2,4]

前序遍历顺序:根节点——>左孩子——>右孩子。

只不过这里不是一般的二叉树,是n叉树,它的孩子节点不是left和right,而是存在了数组children里。但前序遍历就是先遍历根节点,再从左往右遍历孩子节点,所以做法和一般二叉树是一样的,这里用的是dfs解法,先把根节点送去dfs,我们每次存完根结点的值后,从下标0开始遍历根节点的children数组,每次遍历一个点就把它送去下一次dfs。可以准备一个全局数组来存遍历过的节点的val值。

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<int>v;
    void dfs(Node* root)
    {
        if(!root)return;
        v.push_back(root->val);
        int n=root->children.size();
        for(int i=0;i<n;i++)
        {
            dfs(root->children[i]);
        }
    }
    vector<int> preorder(Node* root) {
        dfs(root);
        return v;
    }
};

76. 最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:

对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”

哈希表+滑动窗口。用一个哈希表记录下t的组成情况,然后在遍历s寻找目标字符串的时候用另一个哈希表记录我们找到的字符串的组成情况,起初滑动窗口左端不动右端一直向右延申,当滑动窗口内部的字符串包含了t的时候,滑动窗口的左端开始向右移动收缩窗口,当左端口的元素是t的组成字符,且将此字符排除滑动窗口将使得滑动窗口内部不能完全包含t的时候停下来,直到下次右端点遍历到的字符等于该组成字符时,左端点再继续移动。在此过程中记录最短的字符串,并在遍历结束后输出。

class Solution {
public:
    string minWindow(string s, string t) {
        string str;
        int l = 0, n = s.size(), ans = 0, m = t.size(), min_len = 1e9, sub = -1;
        if (n < m)return str;
        map<char, int>mymap, res;
        for (auto i : t)
            mymap[i]++;
        for (int i = 0; i < n; i++)
        {
            if (mymap[s[i]] != 0 && res[s[i]] < mymap[s[i]])
                ans++;
            if (mymap[s[i]] != 0)
                res[s[i]]++;
            while ( l<n&&mymap[s[l]] == 0||res[s[l]] > mymap[s[l]] )
            {
                if (res[s[l]] > 0)
                    res[s[l]]--;
                l++;
                
            }
            if (m == ans)
            {
                if (i - l < min_len)
                {
                    min_len = i - l;
                    sub = l;
                }
            }
        }
        if (min_len == 1e9)
            return str;
        for (int i = 0; i <= min_len; i++)
        {
            str += s[sub + i];
        }
        return str;
    }
};

代码源——div2每日一题

异或和或 - 题目 - Daimayuan Online Judge

对于一个长度为 n 的0101序列 a1,a2,…,an。

你可以执行以下操作任意多次:

  • 选择两个下标 1≤i,j≤n(i≠j)。
  • 记x=ai xor aj , y=ai or aj , 其中 xor 表示按位异或 , or 表示按位或。
  • 然后令 ai=x,aj=y 或 ai=y,aj=x。

给定两个01序列 s,t , 请你判断是否可以通过有限次(可以为0次)操作将序列 s 变为 t。

输入格式

第一行一个整数 t , 表示数据的组数(1≤t≤103)。接下来 t 组数据:

每组第一行一个01字符串 s(1≤|s|≤10^3),每组第二行一个01字符串 t(1≤|t|≤103)。

注意:|s|可能不等于 |t|。

输出格式

如果可以通过有限次(可以为0次)操作将序列 s 变为 t , 输出 YES , 否则输出 NO

样例输入

2
001
011
11
101

样例输出

YES
NO

样例解释

第一组数据选择 i=2,j=3 , 那么 x=1,y=1 , 接着令 ai=x,aj=y 即可得到 t 序列。

第二组数据 |s|=2,|t|=3 显然无法满足要求。

这题写之前我们先打个草稿来看一下异或和或对于0和1时的各种不同情况,

当两边都是1时:1^1=0,1|1=1。

当两边都是0时:0^0=0,0|0=0。

当其中一边是1时:1^0=1,1|0=1 (反过来也是一样0^1=1,0|1=1)。

通过这几种情况我们不难看出,1是有办法变成0的:11=0,也就是说哪怕我s全是1组成,也可以生成0出来,但是,并不能把所有的1都变成0,毕竟只靠1变成0的方法是:11=0,1|1=1,这样会使得一个1变成0,而另一个依然是1,而只靠1个1是无法变成0的,所以不管怎么样,1是无法被消除干净的,最少也会留下一个1。 0并不能只靠自己变成1:0^0=0,0|0=0,所以说,如果s全是0,那就无法发生任何变化了,毕竟只有0,怎么变都是0。至于一个0一个1的情况,就是可以把一个0变成1,另一个1也是变成1(没变化)。

现在就可以得出结论来了,如果s和t字符串的组成情况,其中一个是没有1,另一个是有1的情况下,两者是不可能变成一样的,毕竟没有1,只靠0是无法变成1的,而如果你有1,那你也无法消除完所有的1变成全是0。至于其他的情况,我们则总是有办法在有限的次数中完成s=t的转化的。还有一点就是,我们一开始就可以先比较他们两个的长度,如果长度不一样那就直接输出NO即可。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<map>
#include<unordered_map>
#include<stack>
#include<queue>

typedef long long ll;
typedef pair<int, int>PII;
const int MOD = 1e9 + 7;
const int N = 100100;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        string s1, s2;
        cin >> s1 >> s2;
        int n = s1.size(), m = s2.size();
        if (n != m)
        {
            cout << "NO" << endl;
            continue;
        }
        int s1_zero = 0, s1_one = 0, s2_zero = 0, s2_one = 0;
        for (int i = 0; i < n; i++)
        {
            if (s1[i] == '0')s1_zero++;
            else s1_one++;

            if (s2[i] == '0')s2_zero++;
            else s2_one++;
        }
        if (s2_one == 0 && s1_one != 0)cout << "NO" << endl;
        else if (s2_one != 0 && s1_one == 0)cout << "NO" << endl;
        else cout << "YES" << endl;
    }

    return 0;
}

CodeForces

Problem - E - Codeforces

Now Dmitry has a session, and he has to pass n exams. The session starts on day 11 and lasts d days. The iith exam will take place on the day of ai (1≤ai≤d), all ai — are different.

imgSample, where n=3, d=12, a=[3,5,9]. Orange — exam days. Before the first exam Dmitry will rest 22 days, before the second he will rest 11 day and before the third he will rest 33 days.

For the session schedule, Dmitry considers a special value μμ — the smallest of the rest times before the exam for all exams. For example, for the image above, μ=1μ=1. In other words, for the schedule, he counts exactly n numbers — how many days he rests between the exam i−1 and ii (for i=0 between the start of the session and the exam ii). Then it finds μ — the minimum among these n numbers.

Dmitry believes that he can improve the schedule of the session. He may ask to change the date of one exam (change one arbitrary value of ai). Help him change the date so that all ai remain different, and the value of μμ is as large as possible.

For example, for the schedule above, it is most advantageous for Dmitry to move the second exam to the very end of the session. The new schedule will take the form:

imgNow the rest periods before exams are equal to [2,2,5][2,2,5]. So, μ=2.

Dmitry can leave the proposed schedule unchanged (if there is no way to move one exam so that it will lead to an improvement in the situation).

Input

The first line of input data contains an integer t (1≤t≤10^4) — the number of input test cases. The descriptions of test cases follow.

An empty line is written in the test before each case.

The first line of each test case contains two integers n and d (2≤n≤2⋅105,1≤d≤109) — the number of exams and the length of the session, respectively.

The second line of each test case contains n integers ai (1≤ai≤d,ai<ai+1), where the ii-th number means the date of the ii-th exam.

It is guaranteed that the sum of nn for all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, output the maximum possible value of μ if Dmitry can move any one exam to an arbitrary day. All values of ai should remain distinct.

Example

input

9

3 12
3 5 9

2 5
1 5

2 100
1 2

5 15
3 6 9 12 15

3 1000000000
1 400000000 500000000

2 10
3 4

2 2
1 2

4 15
6 11 12 13

2 20
17 20

output

2
1
1
2
99999999
3
0
1
9

比赛的时候想到是贪心了,有思路但不会用代码实现啊哭。

首先肯定就是要找到距离最小的那个位置,那个就是我们要修改的考试时间,我们把那个点拿出来,然后重新计算两两点之间的距离,此时,最小距离就有三种可能:

1、重新计算距离后中的最小距离 2、把移出来的那场考试的点移动到最大距离中间后得到的距离 3、把那场考试移动到最后一天

这三种情况得到的距离我们设为min_len,(max_len-1)/2 , d-a[i]-1。因为第一种情况是客观存在的,我们无法对他进行修改,我们只能从第2和第3种情况中取得到距离最大的,然后再和min_len比较,输出较小的那个。

有一点要注意的是,我们一开始求得的最小距离可能和两场考试有关,举个例子,d=10,考试数是:5 7 8 第三场考试前的休息天数是1,那么第二场考完试后的休息天数也是这个1,造成了这个休息天数只有1天的不光只和第三场考试有关,第二长考试也是和这个最短距离挨着的,所以我们还应该假设一下,如果把第二场考试移动到其它地方,可以获得的最小距离是多少。方法和上面一样。最后我们可以从这两个最小距离中选最大的一种结果,这里可以选择是因为我们可以选择移动第二次考试或第三次考试,而不是像求最小距离时那样不能移动考试场数。既然能选我们就要选最大的。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<map>
#include<unordered_map>
#include<stack>
#include<queue>
 
typedef long long ll;
typedef pair<int, int>PII;
const int MOD = 1e9 + 7;
const int N = 100100;
 
int get_min(vector<int>space,int m)
{
    int n = space.size(), max_len = 0, min_len = 1e9;
    for (int i = 1; i < n; i++)
    {
        max_len = max(space[i] - space[i - 1] - 1, max_len);
        min_len = min(space[i] - space[i - 1] - 1, min_len);
    }
    return min(min_len, max((max_len - 1) / 2, m - 1 - space[n - 1]));
}
 
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        int n, m, min_len = 1e9, sub = -1;
        cin >> n >> m;
        vector<int>v(n + 1), space;
        for (int i = 1; i <= n; i++)
        {
            cin >> v[i];
            int len = v[i] - v[i - 1] - 1;
            if (min_len > len)
            {
                min_len = len;
                sub = i;
            }
        }
        for (int i = 0; i <= n; i++)
        {
            if (i != sub)
                space.push_back(v[i]);
        }
        int res = get_min(space, m);
        if (sub > 1)
        {
            space[sub-1] = v[sub];
        }
        res = max(res, get_min(space, m));
        cout << res << endl;
    }
 
    return 0;
}