2022-03-12每日刷题打卡

17 篇文章 1 订阅

2022-03-12每日刷题打卡

代码源——div2每日一题

出栈序列判断 - 题目 - Daimayuan Online Judge

现在有一个栈,有n个元素,分别为1,2,…,n。我们可以通过push和pop操作,将这n个元素依次放入栈中,然后从栈中弹出,依次把栈里面的元素写下来得到的序列就是出栈序列。

比如n=3,如果执行push 1, push 2, pop, push 3, pop, pop,那么我们pop操作得到的元素依次是2,3,1。也就是出栈序列就是2,3,1。

现在给定一个合法的出栈序列,请输出一个合法的由push和pop操作构成的出栈序列。这里要求push操作一定是按1,2,…,n的顺序。

输入格式

第一行一个整数n,接下来一行n个整数,表示出栈序列。

输出格式

输出2n行,每行一个push xpop的操作,可以发现一个出现序列对应的操作序列是唯一的。

样例输入1
3
2 3 1
样例输出1
push 1
push 2
pop
push 3
pop
pop
数据规模

对于100%100%的数据,保证1≤n≤100000,出栈序列一定是个合法的出栈序列。

这题就是很直接的用栈模拟就行,先模拟一边入栈,最后再全部出栈。我们从1到n开始一个个入栈并输出push i,如果入栈的元素对应题目给点出栈序列的元素,则把这个元素出栈并输出pop,然后用当前栈顶元素比较题目所给序列的下一个元素(因为可能会有连续出栈的情况,比如出栈序列是1 5 4 3 2,就是连续出栈四个元素),如果还是相等那就把这个元素也出栈,重复以上操作直到栈为空或者栈顶元素与题目所给序列元素不相等为止。当我们模拟从1到n的入栈后,剩下的就是无脑出栈了,栈内有多少元素就输出多少pop。

(值得一提的是,虽然我们这的时间复杂度是O(n),但仍然会超时,与时间复杂度无关,而是输入输出的问题,如果是个n长的序列,那最后我们会输出2n条语句,而n最大有10w,意味着我们要输出20w语句,这太可怕了,而且cin和cout本身的效率原因是比scanf和priontf偏慢的,所以要么我们使用scanf和printf,或者是关闭流同步。还有就是不要使用endl,换行应该使用‘ ’,对此感兴趣的朋友可以自行搜索下endl的实现方式)

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#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 = 110;
PII que[N * N];
int h[N][N];
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int>v(n);
    for (int i = 0; i < n; i++)cin >> v[i];
    int ans = 0;
    stack<int>sta;
    for (int i = 1; i <= n; i++)
    {
        sta.push(i);
        cout << "push " << i << '
';
        while (!sta.empty()&&sta.top() == v[ans])
        {
            sta.pop();
            ans++;
            cout << "pop" << '
';
        }
    }
    while (!sta.empty())
    {
        sta.pop();
        cout << "pop" << '
';
    }
    return 0;
}

力扣——每日一题

590. N 叉树的后序遍历 - 力扣(LeetCode) (leetcode-cn.com)

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

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

示例 1:

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

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

就很正常的后序遍历二叉树方式,只不过子孩子的节点被存在了根节点的children数组里,而不是单纯的left和right,我们只要for遍历children数组,每次把遍历到的节点送去下次dfs就可以了。其它操作和普通二叉树一样。

/*
// 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;
        int n=root->children.size();
        for(int i=0;i<n;i++)
        {
            dfs(root->children[i]);
        }
        v.push_back(root->val);
    }
    vector<int> postorder(Node* root) {
        dfs(root);
        return v;
    }
};

CodeForces

Problem - A - Codeforces

Consider a playoff tournament where 2^n athletes compete. The athletes are numbered from 1 to 2n.

The tournament is held in nn stages. In each stage, the athletes are split into pairs in such a way that each athlete belongs exactly to one pair. In each pair, the athletes compete against each other, and exactly one of them wins. The winner of each pair advances to the next stage, the athlete who was defeated gets eliminated from the tournament.

The pairs are formed as follows:

  • in the first stage, athlete 1 competes against athlete 2; 3 competes against 4; 5 competes against 6, and so on;
  • in the second stage, the winner of the match "1–2"competes against the winner of the match “3–4”; the winner of the match “5–6” competes against the winner of the match “7–8”, and so on;
  • the next stages are held according to the same rules.

When athletes x and y compete, the winner is decided as follows:

  • if x+yis odd, the athlete with the lower index wins (i.e. if x<y, then x wins, otherwise y wins);
  • if x+y is even, the athlete with the higher index wins.

The following picture describes the way the tournament with n=3goes.

img

Your task is the following one: given the integer nn, determine the index of the athlete who wins the tournament.

Input

The first line contains one integer tt (1≤t≤30) — the number of test cases.

Each test case consists of one line containing one integer n (1≤n≤30).

Output

For each test case, print one integer — the index of the winner of the tournament.

Example

input

2
3
1

output

7
1

Note

The case n=3 is shown in the picture from the statement.

If n=1, then there’s only one match between athletes 1 and 2. Since 1+2=3 is an odd number, the athlete with the lower index wins. So, the athlete 1 is the winner.

题目是说,有2n个选手在进行比赛,每个选手的能量是它们的序好:1~2n,它们一开始先是相邻的一对进行比赛,胜者进入下一轮。

获胜的判断是:

1、如果两名选手的能量之和是偶数,则能量较大的胜出

2、如果两名选手的能量之和是奇数,则能量较小的胜出

一开始是相邻的一对进行比赛,即一奇一偶,此时和为奇数,则较小的(即奇数)胜出,这样第一场都是奇数胜出了。之后是奇数一对的比赛,和自然是偶数,所以较大的胜出,所以第二场也都是奇数胜出。此时我们已经可以发现了,不管比多少场,只有奇数在比赛,因为在第一场时所有的偶数就已经都被淘汰了。而奇数相加必是偶数,所以之后的比赛赢得都是最大的那个。这样最后获胜的就是在1~2n范围内最大的奇数了,即2n-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 main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        ll num = 1;
        cin >> n;
        for (int i = 1; i <= n; i++)
            num *= 2;
        cout << num - 1 << endl;
    }

    return 0;
}
Problem - B - Codeforces

Recently, your friend discovered one special operation on an integer array aa:

  1. Choose two indices i and j (i≠j);
  2. Set ai=aj=|aiaj|.

After playing with this operation for a while, he came to the next conclusion:

  • For every array a of nn integers, where 1≤ai≤10^9, you can find a pair of indices (i,j) such that the total sum of a will decrease after performing the operation.

This statement sounds fishy to you, so you want to find a counterexample for a given integer nn. Can you find such counterexample and prove him wrong

In other words, find an array aa consisting of nn integers a1,a2,…,an (1≤ai≤10^9) such that for all pairs of indices (i,j) performing the operation won’t decrease the total sum (it will increase or not change the sum).

Input

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

The first and only line of each test case contains a single integer nn (2≤n≤1000) — the length of array aa.

Output

For each test case, if there is no counterexample array aa of size nn, print NO.

Otherwise, print YES followed by the array aa itself (1≤ai≤10^9). If there are multiple counterexamples, print any.

Example

input

Copy

3
2
512
3

output

Copy

YES
1 337
NO
YES
31 4 159

Note

In the first test case, the only possible pairs of indices are (1,2) and (2,1).

If you perform the operation on indices (1,2) (or (2,1)), you’ll get a1=a2=|1337|=336, or array [336,336]. In both cases, the total sum increases, so this array a is a counterexample.

这题是说,给你一个数n,让你从1~1e9的数中,找出n个数出来,让他们任意两个数a、b,经过如下变化:a=b=|a-b|后,a+b的和不变小。

简单的数学题,一开始a与b的和为a+b,经过变化后,a与b都变成了|a-b|,此时和为|a-b|+|a-b|。我们现在根据要求建立不等式:

|a-b|+|a-b|>=a+b

化简后就得到了a>=3b或b>=3a。此时我们知道了,只要这两个数中一个是另一个的三倍之大,那么经过变化后,它们的和也不会减少。那么我们就从1开始取,每次取3的次幂即可,同时我们经过计算可知,3^19=1162261467,大于了1e9,这也说明了,3的次幂最多只能取18,那么能满足题目的序列,最多只能有3的0次幂到3的18次幂:共19个数,当n大于19时,我们无法给出合适的序列,输出NO,其余情况我们只要输出3的0次幂到3的n次幂即可。

#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--)
    {
        int n;
        cin >> n;
        if (n > 19)
        {
            cout << "NO" << endl;
        }
        else
        {
            cout << "YES" << endl;
            int ans = 0;
            for (int i = 1; i < 1e9; i *= 3)
            {
                if (ans >= n)break;
                cout << i << " ";
                ans++;
            }
            cout << endl;
        }
    }
    

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值