2024.1.19 寒假训练记录(2)

昨晚的cf打得非常抽象,成功从蓝掉到青,不过在心理预期范围内,可以接受,之后每一场都会跟着打大号,能力的提升比表面上的分数更加重要

文章目录

  • CF 1922A Tricky Template
  • CF 1922B Forming Triangles
  • CF 1922C Closest Cities
  • CF 1922D Berserk Monsters
  • CF 1805A We Need the Zero
  • CF 1805B The String Has a Target
  • CF 1805C Place for a Selfie
  • CF 1805D A Wide, Wide Graph

CF 1922A Tricky Template

题目链接

太久没训了读题能力飞速下滑,昨晚愣是看了好久才看明白题目是啥意思,加上大脑停转最后写了个抽象的模拟

#include 

using namespace std;

#define int long long

using i64 = long long;

typedef pair<int, int> PII;

void solve()
{
    int n; cin >> n;
    string a, b, c;
    cin >> a >> b >> c;
    if (a == c || b == c)
    {
        cout << "NO\n";
        return;
    }
    string ans = "";
    for (int i = 0; i < n; i ++ )
    {
        if (a[i] == b[i]) ans += a[i];
        else{
            if (a[i] != c[i] && b[i] != c[i]) ans += c[i] - 'a' + 'A';
            else ans += "!";
        }
    }
    bool flag = true;
    for (int i = 0; i < n; i ++ )
    {
        if (ans[i] - 'a' < 0)
        {
            ans[i] = 'a' + ans[i] - 'A';
            if (ans[i] == c[i])
            {
                cout << "YES\n";
                return;
            }
        }
        else
        {
            if (ans[i] != c[i])
            {
                cout << "YES\n";
                return;
            }
        }
    }
    cout << "NO\n";
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t = 1;
    cin >> t;
    while (t -- )
    {
        solve();
    }
}

CF 1922B Forming Triangles

题目链接

又是抽象的错误点,没看到二的次方qaq
当较小的两条边是2x和2y时,xy

#include 

using namespace std;

#define int long long

using i64 = long long;

typedef pair<int, int> PII;

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n);
    map<int, int> mp;
    for (int i = 0; i < n; i ++ )
    {
        cin >> a[i];
        mp[a[i]] ++ ;
    }
    sort(a.begin(), a.end());
    int ans = 0;
    mp[a[0]] -- ;
    for (int i = 1; i < n; i ++ )
    {
        mp[a[i]] -- ;
        ans += mp[a[i]] * i;
    }
    cout << ans << '\n';
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t = 1;
    cin >> t;
    while (t -- )
    {
        solve();
    }
}

CF 1922C Closest Cities

题目链接

前两题wa太多次导致写这一题开始急了上手就是个Dijkstra,于是成功t了两发,于是反手就是两个Dijkstra,赛后才发现只有相邻的点有边,非常喜欢小题大做的一个人…

#include 

using namespace std;

#define int long long

using i64 = long long;

typedef pair<int, int> PII;

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i ++ ) cin >> a[i];
    vector<vector<PII>> g(n);
    g[0].push_back(make_pair(1, 1));
    g[n - 1].push_back(make_pair(n - 2, 1));
    for (int i = 1; i < n - 1; i ++ )
    {
        int tmp1 = abs(a[i] - a[i - 1]);
        int tmp2 = abs(a[i] - a[i + 1]);
        if (tmp1 < tmp2)
        {
            g[i].push_back(make_pair(i - 1, 1));
            g[i].push_back(make_pair(i + 1, tmp2));
        }
        else
        {
            g[i].push_back(make_pair(i - 1, tmp1));
            g[i].push_back(make_pair(i + 1, 1));
        }
    }
    int m;
    cin >> m;
    vector<int> dist1(n, 1e9);
    dist1[0] = 0;
    priority_queue<PII, vector<PII>, greater<PII>> q;
    q.push(make_pair(0, 0));
    vector<bool> std(n);
    while (q.size())
    {
        auto t = q.top();
        q.pop();

        int ver = t.second, dd = t.first;

        if (std[ver]) continue;
        std[ver] = true;

        bool flag = false;
        for (int i = 0; i < g[ver].size(); i ++ )
        {
            int j = g[ver][i].first;
            if (dist1[j] > dist1[ver] + g[ver][i].second)
            {
                dist1[j] = dist1[ver] + g[ver][i].second;
                q.push(make_pair(dist1[j], j));
            }
        }
    }

    vector<int> dist2(n, 1e9);
        dist2[n - 1] = 0;
        q.push(make_pair(0, n - 1));
        for (int i = 0; i < n; i ++ ) std[i] = false;
        while (q.size())
        {
            auto t = q.top();
            q.pop();

            int ver = t.second, dd = t.first;

            if (std[ver]) continue;
            std[ver] = true;

            bool flag = false;
            for (int i = 0; i < g[ver].size(); i ++ )
            {
                int j = g[ver][i].first;
                if (dist2[j] > dist2[ver] + g[ver][i].second)
                {
                    dist2[j] = dist2[ver] + g[ver][i].second;
                    q.push(make_pair(dist2[j], j));
                }
            }
        }
    while (m -- )
    {
        int st, ed;
        cin >> st >> ed;
        st -- , ed -- ;
        if (dist1[ed] - dist1[st] < 0) cout << dist2[ed] - dist2[st] << '\n';
        else cout << dist1[ed] - dist1[st] << '\n';
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t = 1;
    cin >> t;
    while (t -- )
    {
        solve();
    }
}

CF 1922D Berserk Monsters

题目链接

因为如果一个人的旁边两个人不改变的话,他在第一局没有挂,之后就都不会挂,所以我们先进行第一轮判断,之后就只需要判断挂的人旁边的两个人即可

#include 

using namespace std;

// #define int long long

using i64 = long long;

typedef pair<int, int> PII;

void solve()
{
    int n;
	cin >> n;
	vector<int> a(n + 1), d(n + 1);
	for (int i = 1; i <= n; i ++ ) cin >> a[i];
	for (int i = 1; i <= n; i ++ ) cin >> d[i];

	vector<int> pre(n + 1), nxt(n + 1);
	for (int i = 1; i <= n; i ++ ) pre[i] = i - 1;
	for (int i = 1; i <= n; i ++ ) nxt[i] = i + 1;
	nxt[n] = 0;

	vector<bool> st(n + 1);
	vector<int> die;
	vector<int> vt;
	for (int i = 1; i <= n; i ++ ) vt.push_back(i);
	for (int i = 0; i < n; i ++ )
	{
		int cnt = 0;
		for (auto t : vt)
		{
			if (st[t]) continue;
			int tmp = d[t];
			// if (pre[t] && !st[pre[t]]) tmp -= a[pre[t]];
			// if (nxt[t] && !st[nxt[t]]) tmp -= a[nxt[t]];
			// if (tmp < 0)
			if (a[pre[t]] + a[nxt[t]] > d[t])
			{
				die.push_back(t);
				cnt ++ ;
				st[t] = true;
			}
		}
		vt.clear();
		for (auto t : die)
		{
			if (nxt[t]) pre[nxt[t]] = pre[t];
			if (pre[t]) nxt[pre[t]] = nxt[t];
			if (!st[pre[t]] && pre[t]) vt.push_back(pre[t]);
			if (!st[nxt[t]] && nxt[t]) vt.push_back(nxt[t]);
		}
		die.clear();

		cout << cnt << ' ';
	}
	cout << '\n';
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t = 1;
    cin >> t;
    while (t -- )
    {
        solve();
    }
}

CF 1805A We Need the Zero

题目链接

熟悉位运算的性质:偶数个相同的数xor后是0,奇数个相同的数xor后是本身

#include 

using namespace std;

#define int long long

using i64 = long long;
using i128 = __int128_t;

typedef pair<int, int> PII;

void solve()
{
    int n;
	cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; i ++ ) cin >> a[i];
	if (n % 2 == 0)
	{
		int tmp = 0;
		for (int i = 0; i < n; i ++ ) tmp ^= a[i];
		if (tmp == 0) cout << 1 << '\n';
		else cout << -1 << '\n';
	}
	else
	{
		int tmp = 0;
		for (int i = 0; i < n; i ++ ) tmp ^= a[i];
		cout << tmp << '\n';
	}
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t = 1;
    cin >> t;
    while (t -- )
    {
        solve();
    }
}

CF 1805B The String Has a Target

题目链接

记录一下最小字符,挪到最前面就行

#include 

using namespace std;

#define int long long

using i64 = long long;
using i128 = __int128_t;

typedef pair<int, int> PII;

vector<i64> p(65);

void solve()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    char minn = 'z' + 1;
    int pos = -1;
    for (int i = n - 1; i >= 0; i -- )
    {
        if (s[i] < minn)
        {
            minn = s[i];
            pos = i;
        }
    }
    if (minn == s[0])
    {
        if (pos != 0)
        {
            cout << minn;
            for (int i = 0; i < n; i ++ )
            {
                if (i != pos) cout << s[i];
            }
        }
        else cout << s;
    }
    else
    {
        cout << minn;
            for (int i = 0; i < n; i ++ )
            {
                if (i != pos) cout << s[i];
            }
    }
    cout << '\n';
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t = 1;
    cin >> t;
    while (t -- )
    {
        solve();
    }
}

CF 1805C Place for a Selfie

题目链接

联立方程看有没有符合条件的解,没有什么坑点

#include 

using namespace std;

#define int long long

using i64 = long long;
using i128 = __int128_t;

typedef pair<int, int> PII;

vector<i64> p(65);

void solve()
{
    int n, m;
    cin >> n >> m;
    vector<int> k(n);
    for (int i = 0; i < n; i ++ ) cin >> k[i];
    sort(k.begin(), k.end());
    while (m -- )
    {
        int a, b, c;
        cin >> a >> b >> c;

        if (c < 0)
        {
            cout << "NO\n";
            continue;
        }

        double tmp1 = b - 2 * sqrt(a * c);
        double tmp2 = b + 2 * sqrt(a * c);

        int pos1 = upper_bound(k.begin(), k.end(), tmp1) - k.begin();
        int pos2 = lower_bound(k.begin(), k.end(), tmp2) - k.begin() - 1;

        if (pos1 < 0 && pos2 >= n) cout << "NO\n";
        else if (pos1 >= 0 && pos1 < n && k[pos1] > tmp1 && k[pos1] < tmp2) cout << "YES\n" << k[pos1] << '\n';
        else if (pos2 >= 0 && pos2 < n && k[pos2] > tmp1 && k[pos2] < tmp2) cout << "YES\n" << k[pos2] << '\n';
        else cout << "NO\n";

    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t = 1;
    cin >> t;
    while (t -- )
    {
        solve();
    }
}

CF 1805D A Wide, Wide Graph

题目链接

考点是树的直径,不太熟悉于是补题的时候去学了下,详细内容见另一篇博客

#include 

using namespace std;

#define int long long

using i64 = long long;
using i128 = __int128_t;

typedef pair<int, int> PII;

vector<i64> p(65);

void solve()
{
    int n;
	cin >> n;
	vector<vector<int>> g(n + 1);
	for (int i = 1; i < n; i ++ )
	{
		int u, v;
		cin >> u >> v;
		g[u].push_back(v), g[v].push_back(u);
	}

	int p, q;
	int c = 0;
	vector<int> d(n + 1);
	
	function<void(int, int)> dfs = [&](int u, int fa)
	{
		for (int i = 0; i < g[u].size(); i ++ )
		{
			int j = g[u][i];
			if (j == fa) continue;
			d[j] = d[u] + 1;
			if (d[j] > d[c]) c = j;
			dfs(j, u);
		}
	};

	dfs(1, 0);
	p = c, c = 0;
	d[p] = 0;
	dfs(p, 0);
	q = c;
	int zj = d[c];

	vector<int> dist1(n + 1, 0x3f3f3f3f);
	vector<int> dist2(n + 1, 0x3f3f3f3f);

	function<void(int, int)> bfs = [&](int start, int idx)
	{
		if (idx == 1) dist1[start] = 0;
		if (idx == 2) dist2[start] = 0;

		priority_queue<PII, vector<PII>, greater<PII>> q;
		q.push(make_pair(0, start));
		vector<bool> st(n + 1);

		while (q.size())
		{
			auto t = q.top();
			q.pop();

			int dd = t.first, ver = t.second;
			if (st[ver]) continue;
			st[ver] = true;

			for (int i = 0; i < g[ver].size(); i ++ )
			{
				int j = g[ver][i];
				if (idx == 1 && (dist1[j] == -1 || dist1[j] > dist1[ver] + 1))
				{
					dist1[j] = dist1[ver] + 1;
					q.push(make_pair(dist1[j], j));
				}
				else if (idx == 2 && dist2[j] > dist2[ver] + 1)
				{
					dist2[j] = dist2[ver] + 1;
					q.push(make_pair(dist2[j], j));
				}
			}
		}
	};

	bfs(p, 1);
	bfs(q, 2);
	vector<int> dist(n + 1);
	for (int i = 1; i <= n; i ++ ) dist[i] = max(dist1[i], dist2[i]);
	dist[p] = dist[q] = 0;

	sort(dist.begin(), dist.end());
	for (int i = 1; i <= n; i ++ )
	{
		int cnt = lower_bound(dist.begin(), dist.end(), i) - dist.begin();
		if (zj < i) cnt -- ;
		else cnt -= 2;
		cout << cnt << ' ';
	}
	cout << '\n';
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t = 1;
    // cin >> t;
    while (t -- )
    {
        solve();
    }
}

你可能感兴趣的:(2024寒假训练记录,算法)