Codeforces Round 898 (Div. 4)

Codeforces Round 898 (Div. 4)

A. Short Sort

解题思路:

遍历所有交换情况,看是否有\(abc\).

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
    string s;
    cin >> s;
    string a = s;
    swap(a[0], a[1]);
    string b = s;
    swap(b[0], b[2]);
    string c = s;
    swap(c[1], c[2]);
    string t = "abc";
    if (s == t || a == t || b == t || c == t)
    {
        puts("YES");
    }
    else
    {
        puts("NO");
    }
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

B. Good Kid

解题思路:

将最小的数字加一.

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
    scanf("%d", &n);
    vector<int> a(n + 1);
    int idx = 0;
    int res = 12312;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        if (a[i] < res)
        {
            res = a[i];
            idx = i;
        }
    }
    a[idx]++;
    ll ans = 1;
    for (int i = 1; i <= n; i++)
    {
        ans *= (ll)a[i];
    }
    printf("%lld\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

C. Target Practice

解题思路:

由于图是固定的,暴力判断每个击中的点属于哪一类即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
char g[100][100];
void solve()
{
    for (int i = 1; i <= 10; i++)
    {
        scanf("%s", g[i] + 1);
    }
    n = 10;
    ll ans = 0;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (g[i][j] == 'X')
            {
                if (i == 1 || i == 10)
                {
                    ans += 1;
                }
                else if (i == 2 || i == 9)
                {
                    if (j == 1 || j == 10)
                    {
                        ans += 1;
                    }
                    else
                    {
                        ans += 2;
                    }
                }
                else if (i == 3 || i == 8)
                {
                    if (j == 1 || j == 10)
                    {
                        ans += 1;
                    }
                    else if (j == 2 || j == 9)
                    {
                        ans += 2;
                    }
                    else
                    {
                        ans += 3;
                    }
                }
                else if (i == 4 || i == 7)
                {
                    if (j == 1 || j == 10)
                    {
                        ans += 1;
                    }
                    else if (j == 2 || j == 9)
                    {
                        ans += 2;
                    }
                    else if (j == 3 || j == 8)
                    {
                        ans += 3;
                    }
                    else
                    {
                        ans += 4;
                    }
                }
                else if (i == 5 || i == 6)
                {
                    if (j == 1 || j == 10)
                    {
                        ans += 1;
                    }
                    else if (j == 2 || j == 9)
                    {
                        ans += 2;
                    }
                    else if (j == 3 || j == 8)
                    {
                        ans += 3;
                    }
                    else if (j == 4 || j == 7)
                    {
                        ans += 4;
                    }
                    else
                    {
                        ans += 5;
                    }
                }
            }
        }
    }
    printf("%lld\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

D. 1D Eraser

解题思路:

从左往右遍历,遇到一个\(B\)就以他为起点向右染白即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d %d", &n, &k);
    string s;
    cin >> s;
    int cnt = 0;
    for (int i = 0; i < n; i++)
    {
        if (s[i] == 'B')
        {
            cnt++;
            int j = 0;
            for (j = i; j <= i + k - 1; j++)
            {
                s[i] = 'W';
            }
            j--;
            i = j;
        }
    }
    printf("%d\n", cnt);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

E. Building an Aquarium

解题思路:

二分高度,暴力判断。

注意本题二分边界,最小取到1。

由于答案上界为\(2\times 10^9\),\(n = 1,a[1] = 10^9,x = 10^9\)

右边界也别取太大,如\(10^{18}\),二分过程会爆\(long \ long\)

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d %d", &n, &k);
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld", &a[i]);
    }
    ll l = 1;
    ll r = 3e9;
    auto check = [&](ll h)
    {
        ll sum = 0;
        for (int i = 1; i <= n; i++)
        {
            sum += max(0ll, h - a[i]);
        }
        if (sum > k)
        {
            return false;
        }
        else
        {
            return true;
        }
    };
    while (l + 1 < r)
    {
        ll mid = l + r >> 1;
        if (check(mid))
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    printf("%lld\n", l);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

F. Money Trees

解题思路:

类似滑动窗口。

从左往右遍历,在线记录以\(i\)为最后一个元素,向左最长可以选择多少元素。

用前缀和计算当前最大区间和。

若区间和大于限制,那么从左端点开始一个个删去,直至区间和合法。此时区间长度就是以第\(i\)个元素为结尾的最长区间。

全局答案就是所有最长区间中的最大值。

注意:左右端点可以相等。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d %d", &n, &k);
    vector<int> a(n + 1), h(n + 1), b(n + 1);
    vector<ll> s(n + 1);
    vector<pii> v;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        s[i] = a[i] + s[i - 1];
    }
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &h[i]);
    }
    ll ans = 0;
    int idx = 0;
    for (int i = 1; i <= n; i++)
    {
        if (i == 1)
        {
            b[i] = 0;
        }
        else if (h[i - 1] % h[i] == 0)
        {
            b[i] = b[i - 1] + 1;
        }
        else
        {
            b[i] = 0;
            // continue;
        }
        int l = max(i - b[i], idx);
        int r = i;
        ll res = s[r] - s[l - 1];
        if (res <= k)
        {
            // cout << i << ' ' << (r - l + 1) << endl;
            ans = max(ans, r - l + 1ll);
        }
        else
        {
            while (res > k)
            {
                res -= a[l];
                l++;
            }
            idx = l;
            ans = max(ans, r - l + 1ll);
        }
    }
    printf("%lld\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

G .ABBC or BACB

解题思路:

我们可以将连续的\(A\)看成\(A\)块。

我们发现,一个\(B\)无论在\(A\)块的左边还是右边,都可以对整个\(A\)块进行连续操作,此时对答案的贡献就是块中\(A\)的个数\(res\)

所以,我们统计\(A\)块的数量\(cnt_a\),同时统计与\(A\)块相邻的\(B\)的数量\(cnt_b\)

如果\(cnt_b >= cnt_a\),那么答案就是\(res\).

否则,答案就是\(res-最小的A块中的A的数量\)。因为\(A\)块就是由\(B\)分割而来,\(min(cnt_b) = cnt_a - 1\)

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    string s;
    cin >> s;
    n = s.size();
    s = ' ' + s;
    int ans = 0;
    int cnt = 0;
    int res = 0;
    vector<int> v;
    for (int i = 1; i <= n; i++)
    {
        char c = s[i];
        if (c == 'A')
        {
            cnt++;
        }
        else
        {
            if (s[i - 1] == 'A' || s[i + 1] == 'A')
            {
                res++;
            }
            if (cnt)
            {
                v.push_back(cnt);
                ans += cnt;
            }
            cnt = 0;
        }
    }
    if (cnt)
    {
        v.push_back(cnt);
        ans += cnt;
    }
    sort(v.begin(), v.end());
    if (res < v.size())
    {
        if (!v.empty())
        {
            ans -= v[0];
        }
    }
    printf("%d\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

H. Mad City

解题思路:

首先,如果二者起点一样肯定寄。

\(n\)个点,\(n\)条边,图中一定有且仅有一个环。

否则如果\(b\)在环上,一定无敌。

如果\(b\)不在环上,一定要到环上才能永久兜圈子无敌,所以他要最快到环上。

所以,\(a\)要做的就是堵到\(b\)到环上的那个点。大家一起动,如果\(a\)能够快一步到那个点,那么\(b\)就无法永久不被抓到。

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
typedef pair<int,int> pii;
#define fi
#define se

void solve()
{
	int n,a,b;
	scanf("%d %d %d",&n,&a,&b);
	vector<vector<int>> adj(n + 10);
	for(int i = 1;i<=n;i++)
	{
		int x,y;
		scanf("%d %d",&x,&y);
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	vector<bool> st(n + 1),isc(n + 1);
	vector<int> ver;
	int tag = 0;
	auto dfs =[&](auto self,int u,int fa) -> void
	{
//		cout<<u<<' ';
		st[u] = true;
		for(auto v : adj[u])
		{
			if(v == fa)
			{
				continue;
			}
			if(st[v])
			{
				if(!isc[v])
				{
					ver.push_back(v);
					tag = v;
					isc[u] = true;
				}
				continue;
			}
			self(self,v,u);
			if(isc[v])
			{
				isc[u] = true;
				ver.push_back(v);
			}
			if(tag == u)
			{
				isc[u] = false;
			}
		}
	};
	dfs(dfs,1,-1);
	vector<int> dist(n + 1,-1);
	auto bfs =[&](int x) -> int
	{
		queue<int> q;
		q.push(x);
		dist[x] = 0;
		if(isc[x])
		{
			return x;
		}
		while(q.size())
		{
			auto u = q.front();
			q.pop();
			for(auto v : adj[u])
			{
				if(dist[v] != -1)
				{
					continue;
				}
				if(isc[v] || v == tag)
				{
					dist[v] = dist[u] + 1;
					return v;
				}
				dist[v] = dist[u] + 1;
				q.push(v);
			}
		}
	};
	auto bfs1 =[&](int s,int e) -> int
	{
		vector<int> d(n + 1,-1);
		queue<int> q;
		q.push(s);
		d[s] = 0;
		if(s == e)
		{
			return 0;
		}
		while(q.size())
		{
			auto u = q.front();
//			cout<<u<<endl;
			q.pop();
			for(auto v : adj[u])
			{
				if(d[v] != -1)
				{
					continue;
				}
				if(v == e)
				{
					return d[u] + 1;
				}
				d[v] = d[u] + 1;
				q.push(v);
			}
		}
	};
	if(a == b)
	{
		puts("NO");
		return;
	}
	else if(b == tag || isc[b])
	{
		puts("YES");
		return;
	}
	int t = bfs(b);
//	cout<<t<<endl;
	if(bfs1(a,t) <= dist[t])
	{
		puts("NO");
	}
	else
	{
		puts("YES");
	}
}
int main()
{
	int t = 1;
	cin >> t;
	while(t--)
	{
		solve();
	}
	return 0;
}
posted @ 2023-09-22 13:54  value0  阅读(258)  评论(0)    收藏  举报