Pinely Round 2 (Div. 1 + Div. 2) A~D

A. Channel

题意:有n个订阅者,a个初始在线人数,q个上下线情况,问是否一定或有可能所有订阅者都阅读了新的帖子。

思路:同时在线人数等于n时,一定都阅读了,输出YES。初始在线人数加上所有的上线人数(所有的+号)大于等于n的话输出MAYBE。否则输出NO。

AC代码

#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define int long long
using namespace std;
const int N = 100010;
void solve()
{
    int n, a, q;
    cin >> n >> a >> q;
    string arr;
    cin >> arr;
    int jia = a;
    if (a == n)
    {
        cout << "YES" << endl;
        return;
    }
    for (int i = 0; i < arr.size(); i++)
    {
        jia += (arr[i] == '+');
        a += (arr[i] == '+');
        a -= (arr[i] == '-');
        if (a == n)
        {
            cout << "YES" << endl;
            return;
        }
    }
    if (jia >= n)
    {
        cout << "MAYBE" << endl;
        return;
    }
    cout << "NO" << endl;
}
signed main()
{
    int t;
    cin >> t;
    //t = 1;
    while (t--)
    {
        solve();
    }
}

B. Split Sort

题意:给出一个排列,可以进行一个操作:选定一个数后,按原先顺序先写出小于这个数的数,再写出大于这个数的数。问最少需要多少步可以使ai = i。

思路:对于一个数a,如果它的位置要大于a + 1的话,那么必须选定a + 1来操作一次,记录所有这样的数的和,即为最小步数。

AC代码

#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define int long long
using namespace std;
const int N = 100010;
int a[N], p[N];
void solve()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        p[a[i]] = i;
    }
    
    int ans = 0;
    for (int i = 1; i < n; i++)
    {
        ans += (p[i] > p[i + 1]);
    }

    cout << ans << endl;
}
signed main()
{
    int t;
    cin >> t;
    //t = 1;
    while (t--)
    {
        solve();
    }
}

C. MEX Repetition

题意:给出一个数列,对数列进行k次下列操作:从a1到an,依次用数列的MEX值替代,数列的MEX值为没有出现在数列中的最小值。

思路:当对数列进行n + 1次操作时,数列会变回初始情况,所以k要先模一下n + 1,每做一次操作相当于滑动数组向右滑动了一次,例如1 2 3 4 5每次操作后为:

0 1 2 3 4

5 0 1 2 3

4 5 0 1 2

3 4 5 0 1

2 3 4 5 0

1 2 3 4 5

数列的MEX值为1到n + 1的和减去当前数列的和。

AC代码

#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define int long long
using namespace std;
const int N = 100010;
int a[N];
int d[N];
void solve()
{
	int n, k;
	cin >> n >> k;
	int sum = 0;
	int p = (n + 1) * n / 2;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		sum += a[i];
	}
	a[n + 1] = p - sum;
	n += 1;
	if (k == n)
	{
		for (int i = 1; i <= n - 1; i++)
			cout << a[i] << " ";
		cout << endl;
		return;
	}

	if (k > n)
	{
		int x = k % n;
		k = x;
	}
	for (int i = n - k + 1; i <= n; i++)
	{
		cout << a[i] << " ";
	}
		
	for (int i = 1; i <= n - k - 1; i++)
	{
		cout << a[i] << " ";
	}

	cout << endl;
}
signed main()
{
    d[0] = 0;
    for (int i = 1; i <= 100000; i++)
    {
        d[i] = d[i - 1] + i;
    }
    int t;
    cin >> t;
    //t = 1;
    while (t--)
    {
        solve();
    }
}

D. Two-Colored Dominoes

题意:棋盘上有若干个多米诺骨牌,每个牌占据两个格子,上下两个或者左右两个。要求用黑白颜色给多米诺骨牌涂色,每个多米诺骨牌的两个格子必须不同颜色,同一列和同一行的黑白颜色数必须相等。如果不能输出-1。

思路:如果在同一行或同一列的多米诺骨牌所在格子为奇数,则不可能涂色。横着的多米诺不会影响这一行的得黑白数,竖着的不会影响这一列的黑白数。所以遍历每一行,将每个竖着的多米诺依次涂成黑,白,黑,白....(竖着的多米诺每一行一定有偶数个)。遍历每一列,将每个横着的多米诺依次涂为黑,白,黑,白.....(横着的多米诺每一列一定有偶数个)。

AC代码

#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define int long long
using namespace std;
const int N = 510;
char arr[N][N];
int ans[N][N], col[N], lie[N];
int colsum[N], liesum[N];
typedef pair<int, int> pll;
int n, m;
int check()
{
    memset(colsum, 0, sizeof colsum);
    memset(liesum, 0, sizeof liesum);

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            //cin >> arr[i][j];
            if (arr[i][j] != '.')
            {
                colsum[i]++;
                liesum[j]++;
            }
        }
    int flag = 1;
    for (int i = 1; i <= n; i++)
    {
        if (colsum[i])flag = 0;
        if (colsum[i] % 2)
        {
            cout << -1 << endl;
            return 1;
        }
    }
    for (int j = 1; j <= m; j++)
    {
        if (liesum[j] % 2)
        {
            cout << -1 << endl;
            return 1;
        }
    }

    if (flag)
    {
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {

                cout << '.';
            }
            cout << endl;
        }
        return 1;
    }

    return 0;
}
void solve()
{
    
    cin >> n >> m;

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> arr[i][j];
        }
    }

    if (check())
    {
        return;
    }

    int cnt = 1;

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            if (arr[i][j] == 'U')
            {
                ans[i][j] = cnt;
                ans[i + 1][j] = cnt * -1;
                cnt *= -1;
            }
        }
    }
    
    cnt = 1;
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (arr[j][i] == 'L')
            {
                ans[j][i] = cnt;
                ans[j][i + 1] = cnt * -1;
                cnt *= -1;
            }
        }
    }

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            if (arr[i][j] == '.')
            {
                cout << ".";
                continue;
            }
            if (ans[i][j] == 1)
            {
                cout << "W";
            }
            else cout << "B";
        }
        cout << endl;
    }
}
signed main()
{
    int t;
    cin >> t;
    //t = 1;
    while (t--)
    {
        solve();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值