Codeforces Round #831 (Div. 1 + Div. 2)

Posted on 2022-10-29 20:47  Capterlliar  阅读(168)  评论(0编辑  收藏  举报

A. Factorise N+M

题意:给出一个质数,求另一个质数,使得两个数之和不是质数。

解:把那个质数再输出一遍就行了。

B. Jumbo Extra Cheese 2

题意:给出一些长方形,按照以下规则把长方形拼起来:

1. 每个长方形的一条边和x轴重合,长方形之间边互相平行;

2. 长方形之间不能重叠;

3.所有长方形联通。

求拼起来后最小周长。

解:把所有长方形较短的边贴到x轴上,这样整个图形周长为(短边之和 + 最高的高)*2.

(一开始看样例以为能叠起来,困惑了很久,发现那是非法例子)

C. Bricks and Bags

题意:给出一堆砖和三个袋子,每块砖有一个重量。把所有砖都放到袋子里,保证每个袋子里至少有一块砖,从第i个袋子里拿出的砖重wi。然后B来了,他会从每个袋子里拿一块砖,使得 value = |w1−w2|+|w2−w3| 最小。现在你来放砖,使得B得到的value最大,求这个最大值。

解:最终结果是两边减中间之和,先假设把最小值放中间,最大值放左边,右边肯定拿次大值。考虑例子:1,2,99,100,这组数中最优解是把1,2放中间,当砖重量差异很大的时候把最小值单独放中间不一定是最优解,但可以枚举中间放几个最小值。最大值放中间同理,可以都枚举一遍。

D. Knowledge Cards

题意:有一个m*n的格子阵(m≥3, n≥3),(1, 1)的位置放了一叠纸牌,每个纸牌上有一个数字,整叠牌是k的一个排列。现在要移动这叠牌到(m, n)去,并且在(m, n)处以:最下面是k,最上面是1的顺序叠成一叠。每次可以把一张牌挪到相邻的四个格子去,除了起点和终点,每个格子只能有一张牌。也就是说,如果相邻格子有牌,就不能挪过去了。并且,每张牌离开(1, 1)就不能回去;到达(m, n)也不能离开。问是否有这样一种方案,使得在每个操作合法的情况下把这叠牌挪过去。

解:首先第一次要把n挪过去,第二次把n-1挪过去,以此类推。如果要把n挪过去,就要把n之前的牌都放到空格子里去,如果放不下,肯定无解。接下来考虑最少留几个空位能把n挪过去。有点像以前铅笔盒上那个拼图,从那个拼图能拼起来可以猜测(……)留一个空位就能把任何一个格子上的牌送到终点。考虑过空位连一条过起点和终点的环,然后循环向前,因为全图大于等于3*3所以这个环必然存在。接下来只要检测轮到第i个数时图里是否有一个空位即可。

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxx 300005
#define maxn 25
#define maxm 205
#define ll long long
#define inf 1000000009
#define mod 998244353
int a[maxx],pos[maxx];
signed main() {
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=k;i++){
            scanf("%d",&a[i]);
            pos[a[i]]=i;
        }
        int now=0,empty=n*m-2;
        for(int i=k;i>=1;i--){
            int p=pos[i];
            if(p>now){
                if(p-now-1>=empty-1) {
                    printf("TIDAK\n");
                    goto nxt;
                }
                else{
                    empty-=(p-now-1);
                }
                now=p;
            }
            else{
                empty++;
            }
        }
        printf("YA\n");
        nxt:;
    }
    return 0;
}
View Code