Educational Codeforces Round 123

Posted on 2022-02-23 16:15  Capterlliar  阅读(37)  评论(0编辑  收藏  举报

A - Doors and Keys

模拟即可

B - Anti-Fibonacci Permutation

题意:构造n个非斐波那契数列,即一个n的排列,对任意a[i],a[i+1],a[i+2],a[i]+a[i+1]!=a[i+2]。

解:递减的数列显然符合要求。考虑构造n-x,n-x-1,...1,n,n-1,...n-x+1,n=3时不成立,特判即可。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define maxn 1005
#define maxm 200005
#define eps 0.00000001
#define inf 0x7fffffff
#define mod 1000000007
//#define int long long
int n,k;
signed main() {
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        if(n==3){
            printf("3 2 1\n");
            printf("1 3 2\n");
            printf("3 1 2\n");
            continue;
        }
        for(int i=n;i>=1;i--){
            for(int j=i;j>=1;j--)
                printf("%d ",j);
            for(int j=n;j>=i+1;j--)
                printf("%d ",j);
            printf("\n");
        }
    }
    return 0;
}
//n-x,n-x-1,...1,n,n-1,...n-x+1
//n!=3
View Code

C - Increase Subarray Sums

题意:令f(x)为给数列a中任意x个数加k后最大子数组的和,求f(0),f(1),...,f(n)的值。

解:首先排除n3的算法。dp了一下失败了,其实也能做,设dp[i][j][0/1]为到第i个,用了j个k,当前加不加k的答案。

考虑f(x)和什么有关。首先它要加k个数在不同的位置,那最好全加在子数组里面。令len[i]为长度为i的子数组元素和最大值。

f(k)=max(len[i]...len[n])+k*x

好了可以写了。注意继承之前的最大值,因为不是多出一个数和就会变大的。

D. Cross Coloring

题意:一开始有一个空白的n*m表格,每次选一个格子,将其行或列染成k种颜色中的随机一种,求最后表格有几种染色情况。

解:染色问题肯定从后往前看。对于某一行或某一列,只有一种染色情况。不同行和列染色之间互不干扰,多染一次色,就多k种不同的情况。也就是说,选的格子所在行或列没有被选过,则乘k。注意所有行或所有列都被涂过色后整张表格显然已经满了,任何之前的染色操作都被覆盖,但此时记录行和列的set仍不完全,应立即退出循环。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define maxn 1005
#define maxm 200005
#define eps 0.00000001
#define inf 0x7fffffff
#define mod 998244353
//#define int long long
int n,m,k,q;
int ql[maxx],qr[maxx];
signed main() {
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d%d",&n,&m,&k,&q);
        for(int i=1;i<=q;i++)
            scanf("%d%d",&ql[i],&qr[i]);
        set<int> l,r;
        ll ans=1;
        for(int i=q;i>=1;i--){
            if(l.size()==n||r.size()==m)
                break;
            int flag=0;
            if(!l.count(ql[i]))
                l.insert(ql[i]),flag=1;
            if(!r.count(qr[i]))
                r.insert(qr[i]),flag=1;
            if(flag)
                ans=(ans*k)%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}
View Code