Codeforces Round #573 (Div. 2) //B:二维数组标记法 C:直接模拟//

A:

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int n;
	scanf("%d",&n);
	n%=4;
	if(n==1)
	{
		printf("0 A");
	}
	else if(n==2)
	{
		printf("1 B");
	}
	else if(n==3)
	{
		printf("2 A");
	}
	else
	{
		printf("1 A");
	}
	return 0;
}

 

B:

题意:输入三张牌,输出换牌次数最少的换牌数。当你有顺子或者三张完全相同的时候即可

思路:直接模拟即可,分析得出当三张牌是顺子或者完全相同时,不用换牌;

代码:

#include<bits/stdc++.h>
using namespace std;
int vis[5][10];
char s[3][3];
int main()
{
    for(int i = 0;i < 3; i++)
    {
        cin >> s[i];
        int tmp = s[i][0] - '0';
        if(s[i][1] == 's')
            vis[1][tmp]++;
        else if(s[i][1] == 'm')
            vis[2][tmp]++;
        else if(s[i][1] == 'p')
            vis[3][tmp]++;
    }
    for(int i = 1;i <= 3; i++)
    {
        for(int j = 1;j <= 9; j++)
        {
            if(vis[i][j] == 3 || (vis[i][j-1] == 1 && vis[i][j] == 1 && vis[i][j+1] == 1))
            {
                cout << "0" << endl;
                return 0;
            }
        }
    }
    for(int i = 1;i <= 3; i++)
    {
        for(int j = 1;j <= 9; j++)
        {
            if(vis[i][j] == 2)
            {
                cout << "1" << endl;
                return 0;
            }
            if((vis[i][j-1] == 1 && vis[i][j] ==1) || (vis[i][j] == 1 && vis[i][j+1] == 1) || (vis[i][j-1] == 1 && vis[i][j+1] == 1))
            {
                cout << "1" << endl;
                return 0;
            }
        }
    }
    cout << "2" << endl;
    return 0;
}

 

C(直接模拟):

题意:给一个n,那么就有一串数字1~n,给定一个k,表示从开头开始每k个数算一页,给一个数m,表示特殊的数的个数,接下来一行给出这m个特殊的数,包含至少一个特殊的数为特殊的页,从头开始找到第一个特殊的页,每次删除这页里的所有特殊的数,后面的数都要向前移,最后一页的数可以不装满整页,直至特殊的数被删光。问要这样删除多少次。
 

思路:

直接模拟

 

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 100010;
int a[maxn],n,m,k;
signed main()
{
    cin >> n >> m >> k;
    for(int i = 1;i <= m; i++)
        cin >> a[i];
    int pos = 1,ans = 0,tmp = k;
    while(pos <= m)
    {
        int cnt = 0;
        while(pos <= m && a[pos] <= tmp)
        {
            pos++;
            cnt++;
        }
        while(cnt)
        {
            ans++;
            tmp += cnt;
            cnt = 0;
            while(pos <= m && a[pos] <= tmp)
            {
                pos++;
                cnt++;
            }
        }
        if(pos <= n)
            tmp += (a[pos] - tmp - 1) / k * k + k;
    }
    cout << ans << endl;
    return 0;
}

 

D(博弈类):

题意:

现在有nn堆石子,每堆石子数量为aiai​,现在sjf和csl两个人轮流拿,sjf先手,当石子被拿完时,轮到谁拿谁输,但是如果某人拿完之后剩下的石子有两堆数目相同时则刚刚拿的人输。

 

思路:

先排序;然后,就会发现,有些情况是一开始就输的,具体情况如下:

  1. 有两个 两个相等非零数。(a[x] == a[x+1], a[y] == a[y+1], x != y)
  2. 有两个零。 (a[x] == a[y] == 0)
  3. 有一个(a[x] + 1 == a[x+1] == a[x+2]),此时也直接输。

判完后,可以证明,无论他们怎么取,只要不使自己输,都会形成类似序列{0,1,2,3,...}的情况。

此时,只要判断一下石子总数减去最终状态的奇偶性即可。

 

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 1e5+100;

ll n, num[maxn], sum;//分别记录石子堆数,每堆的数量,石子总数
map <ll, ll> maps;//记录某一数量的石子有多少堆

int main() 
{
    scanf("%lld", &n);
    for(int i=1;i<=n;i++) 
    {
        scanf("%lld", &num[i]);
        sum += num[i];
        maps[num[i]]++;
    }
    sort(num+1, num+1+n);
    for(int i=3;i<=n;i++) 
    {
        if(num[i] == num[i-1] && num[i]-num[i-2] == 1) //数量为k-1,k,k
        {
            printf("cslnb");
            return 0;
        }
    }

    map <ll, ll> :: iterator iter;
    int cnt = 0;
    for(iter=maps.begin();iter!=maps.end();iter++) 
    {
        if(iter->second > 2) {//数量相同石子堆数大于2
            printf("cslnb");
            return 0;
        } 
        else if(iter->second == 2) 
        {
            cnt++;
        }
    }
    if(cnt >= 2 || maps[0] >= 2) 
    {
        printf("cslnb");
        return 0;
    }

    bool flag= false;
    sum -= n*(n-1)/2;//检验差值的奇偶性
    if(sum%2 == 0) 
    {
        flag = true;
    }

    if(flag) printf("cslnb");
    else printf("sjfnb");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值