Codeforces Round 884 (Div. 1 + Div. 2)

A. Subtraction Game

题意:博弈论,两个人先后从一堆石子中取a或b个石子,最先无法取得石子得人fail,输入给出a和b,要求输出n使得先手开局必输。

思路:只需要使n=a+b,这样无论先手选哪个,后手只需要选剩下的数量就开始直接刚好拿完n个石子,所以只需要输出a+b

ac代码:(不放了太水了)

B. Permutations & Primes

题意:定义一组数的mex为这一组数种不存在的最小正整数,定义”primality“为一个数组中满足以下定义的(l,r)的数量,定义:数组下标l到r的数的mex为素数,输入给出整数n,要求寻找”primality“最大的1到n的排列,通俗来讲就是找出最多子集的mex为素数的1到n的排列

思路:由于任何包含1且不含2的子集的mex都是2,任何包含1和2但是不包含3的子集的mex都是3,都是合法子集,所以我们需要包含1的子集尽可能多,但是2要尽可能离1远,并且3要尽可能离1和2远,所以只需要将第一位放2或3,另外一端放另一个数,中间放1即可(至于正确性的证明。。。我们就姑且当他是一个天理吧)(bushi)

trick:2和3作为最小的两个素数,而且还是连续出现的自然数,在这种关于素数和排列的问题中要特殊考虑,而此题是关于mex的问题,1又是唯一小于这两个最小素数的非素数自然数,所以着重考虑123这较为特殊的三个数

ac代码:(太水了也不放了)

C. Particles

题意:给出n个数的数组,可以进行以下操作直至数组中仅剩一个数,operation:消去数组中的某个数,然后该数两边的数相融合为一个数,大小为两数之和,要求找出在操作不能进行后能得到剩余数的最大值

思路:通过观察数组的操作易知以下规律:每次操作之后数组的数的数量都会减2,而且操作之后原数的下标的奇偶性不变,包括融合的两个数,所以不论操作顺序如何,剩余数一定是某些奇数位或者偶数位的数字之和,所以我们可以计算出奇数位的最大子序列和和偶数位的最大子序列和然后输出最大值即可,注意特判全为负数的情况。

ac代码:

#include
#define endl '\n'
#define ll long long
#define INF 0x3f3f3f3f
#define pb push_back
#define int long long
#define Mirai ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef pair pii;
const int N=2e5+10;
int n;
int a[N];
void solve()
{
    cin>>n;
    int ma=-INF;
    bool allfu=true;
    int sum1=0,sum2=0;
    for(int i=0;i>a[i];
        if(a[i]>=0)allfu=false;
        ma=max(ma,a[i]);
    }
    if(allfu)cout<0)sum1+=a[i];
            if(i%2==0&&a[i]>0)sum2+=a[i];
        }
        cout<>T;
    while(T--)
    {
        solve();
    }
}

D. Row Major

题意:输入给出正整数n,然后要求给出符合以下条件的字符串:1、该字符串的排列方式改为n*m的矩阵排列,要求排列中没有相同字符相邻(此处位4联通相邻),2、要求给出的字符串出现的不同字符最少

思路:假设字符串长度为len,可以组成的所有矩阵的边长即为len的所有因子,所以排列在还换行的时候就会进入上下相邻的状态,我们只需要将字符串的最小相同字符距离控制在len的最下非因子即可

ac代码:

#include
#define endl '\n'
#define ll long long
#define INF 0x3f3f3f3f
#define pb push_back
#define int long long
#define Mirai ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef pair pii;
const int N=1e6+10;
int n;
void solve()
{
    cin>>n;
    int m=1;
    while(n%m==0)m++;
    string s;
    for(int i='a';i<='a'+m-1;i++)s+=(char)i;
    int cnt=n/m+(n%m!=0);
    string t;
    for(int i=0;i>T;
    while(T--)
    {
        solve();
    }
}

你可能感兴趣的:(Codeforces,算法,数据结构)