codeforces hello 2020

题目链接:https://codeforces.com/contest/1284

A:New Year and Gaming

题目大意为存在n个字符串S1,S2....Sn和m个字符串t1,t2....tn,对每个年份,需要找到对应的S和对应的t并把它们相连。规则为从第一年开始,对应第一个字符串,后每年都会向后移动一个字符串,当到达最后一个字符串时,下一年会回到第一个字符串。
样例大意为输入n个字符串S1,S2....Sn,之后输入m个字符串t1,t2....tn。然后需要回答q个询问,每个询问为一个整数y代表年份。各个数值范围为n,m(1≤n,m≤20),字符串长度大于1小于10,1≤q≤2020,1≤y≤109

此题我的解法为分别查找两个字符串序列的对应位置,直接%就可以,若为0则转成最后的n或m即可。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define pb push_back
#define ll long long
#define pii pair<int,int>
#define INF 0x3f3f3f3f
string ss1[25],ss2[25];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        cin>>ss1[i];
    for(int i=1;i<=m;i++)
        cin>>ss2[i];
    int q;
    scanf("%d",&q);
    while(q--)
    {
        int t;
        scanf("%d",&t);
        int t1=t%n;
        int t2=t%m;
        if(!t1)t1=n;
        if(!t2)t2=m;
        cout<<ss1[t1]<<ss2[t2]<<endl;
    }
    return 0;
}

B:New Year and Ascent Sequence

题目大意为在给出的n个序列中将任意两个组合(不改变顺序,可与自身组合)后存在升序(即为位置靠前的数小于位置靠后的数)。
输入整数n(1≤n≤1e5),接下来的n行都以一个l(1≤l,l表示此序列的长度)开头,后面跟l个数字Si,j(0≤Si,j≤106),所有l的和不能大于1e5。

此题解法为存储每个序列的最大值和最小值,同时判定此序列中是否本身存在升序。后将最小值+1的数量做前缀和,若本身存在升序,则将最小值+1设为0加入前缀和。最后用最大值从前缀和中取就可以。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define pb push_back
#define ll long long
#define pii pair<int,int>
#define INF 0x3f3f3f3f
const int maxn=1e6+7;
int minn[maxn],maxx[maxn];
bool ok[maxn];
int mmm[maxn];
int main()
{
    int n;
    ll sum=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int l;
        scanf("%d",&l);
        int a;
        int max1,min1;
        scanf("%d",&max1);
        min1=max1;
        for(int j=2;j<=l;j++)
        {
            scanf("%d",&a);
            if(a<min1)min1=a;
            if(a>min1)ok[i]=1;
            if(a>max1)max1=a;
        }
        maxx[i]=max1;
        minn[i]=min1;
        if(ok[i])mmm[0]++;
        else mmm[min1+1]++;
    }
    for(int i=1;i<maxn;i++)
        mmm[i]+=mmm[i-1];
    for(int i=1;i<=n;i++)
    {
        if(ok[i])sum+=n;
        else{
            sum+=mmm[maxx[i]];
        }
    }
    cout<<sum<<endl;
    return 0;
}

C:New Year and Permutation

此题是找个连续的子序列,让最大值减最小值等于长度减一,可以看出符合的都是在大小连续的子序列中。由此只需要计算排列就行了。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define pb push_back
#define ll long long
#define pii pair<int,int>
#define INF 0x3f3f3f3f
const int maxn=250007;
ll fa[maxn];
int main()
{
    int n,mod;
    fa[0]=1;
    scanf("%d%d",&n,&mod);
    for(int i=1;i<=n;i++)fa[i]=fa[i-1]*i%mod;
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        sum+=((n-i+1)*(fa[i]*fa[n-i+1]%mod))%mod;
        sum%=mod;
    }
    cout<<sum<<endl;
}

D没写出来,等考完再补。

猜你喜欢

转载自www.cnblogs.com/gxywjl/p/12152217.html