【浮*光】【Codeforces Round #480 (Div. 2)】解题报告

980A - Links and Pearls

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <queue>
using namespace std;
typedef long long ll;

/*【题意】有一个环形项链,‘-’代表连接的链,‘o’代表珍珠,
可以随意拆,随意组装,只能使用现有的-和o,不可以丢掉,
能否组合成:每个珍珠之间的链的长度都相等。
【分析】因为是环,所以有几个珍珠,就必然有几个间隔,
这些间隔内的链长都相等,即链的总数整除珍珠总数即可YES,否则NO。
特判:没有珍珠,判定为YES。  */

char ss[110];  
int main(){  
    while(~scanf("%ss",ss+1)){  
        ll len=strlen(ss+1),ans1=0,ans2=0;  
        for(ll i=1;i<=len;i++){  
            if(ss[i]=='o') ans1++;//统计个数  
            else ans2++;  
        }  
        if(ans1==0){ printf("YES\n"); continue; } //特判  
        if(ans2%ans1==0) printf("YES\n");
        else printf("NO\n");  
    }  
    return 0;  
}  


980B - Marlin

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <queue>
using namespace std;
typedef long long ll;
/* 给你一个4*n的网格,保证n为奇数,让你在其中放k个障碍物(不能放在边界)
使得【从左上角走到右下角的最短路的方案数】等于【左下走到右上的最短路的方案数】
分析》由于给出的条件 3≤n≤99, 0≤k≤2×(n−2) ————> 一定可以
1" k为偶数时,以{纵向为对称轴}进行摆放即可。
2" ①k为奇数且小于等于n-2时,{横向对称}摆放:
...........
...........
...#####...
...........
②k等于n时:
.............
.#.........#.
.###########.
.............
③k大于n时,在上图空闲的位置随便填即可。   */
int n,K; char a[6][105];
int main(){
    scanf("%d%d",&n,&K);
    for(int i=1;i<=4;++i)//初始化为无障碍
        for(int j=1;j<=n;++j) a[i][j]='.';
    puts("YES");//0≤k≤2×(n−2),一定可以
    if(K%2==0){
        K/=2; //偶数的情况:按照纵向对称放置,↓↓可在2,3行随意选择
        for(int i=1;i<=K;++i) a[2][i+1]=a[3][i+1]='#';
    }
    else{//模拟奇数的情况
        if(n==1) a[2][2]='#';
        else if(K<=n-2){
            for(int i=1,j=(n-K)/2+1;i<=K;++i,++j)
                a[3][j]='#'; //先摆第三行
        }
        else if(K==n){
            for(int i=1,j=2;i<=n-2;++i,++j)
                a[3][j]='#';
            a[2][2]=a[2][n-1]='#'; //对称
        }
        else{
            for(int i=1,j=2;i<=n-2;++i,++j)
                a[3][j]='#';
            a[2][2]=a[2][n-1]='#';
            for(int i=3,j=1;i<=n-2 && j<=K-n;++i,++j){
                a[2][i]='#';
            }
        }
    }
    for(int i=1;i<=4;++i){
        for(int j=1;j<=n;++j) putchar(a[i][j]);
        printf("\n");
    }
    return 0;
}
//——The Solution By AutSky_JadeK From UESTC 
//出处:http://www.cnblogs.com/autsky-jadek/

980C - Posterized

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <queue>
using namespace std;
typedef long long ll;

/* 给出n个数,都属于区间[0,255],把[0,255]划分成多个长度 <=k 的不重叠的子区间。
每个数必须包含在一个子区间内,且这个数的价值是这个子区间的左端点。
要求 这n个价值 字典序最小,输出最小价值和时的各个价值。 */

/* 分析》字典序最小,即定区间时左端点尽量小。
枚举 区间[p[i]-k+1,p[i]] 定左端点l,如果这个区间内最大的后缀没有被占用,
即 [l, p[i]] 内的数都没被占用。右端点暂时定在 p[i] 。
因为 l-1 位置肯定已经被另一个区间占用了,判断能否合并,
<----(合并条件)l-1 位置的区间的左端点能拓展到 p[i] 位置。  */

bool b[256];
int n,k,p[256];
int main(){
    int x,t,tt; scanf("%d%d",&n,&k);
    for(int i=1;i<=n;++i){
        scanf("%d",&x); t=-1;
        for(int j=x;j>=0;--j)
            if(b[j]){ t=j; break; }
        if(t==-1){
            if(x>=k){
                b[x-k+1]=1; p[x-k+1]=x;
                printf("%d%c",x-k+1,i==n ? '\n' : ' ');
            }
            else{
                b[0]=1; p[0]=x;
                printf("0%c",i==n ? '\n' : ' ');
            }
        }
        else if(t+k-1<x){
            tt=max(x-k+1,p[t]+1);
            b[tt]=1; p[tt]=x;
            printf("%d%c",tt,i==n ? '\n' : ' ');
        }
        else{
            p[t]=max(p[t],x);
            printf("%d%c",t,i==n ? '\n' : ' ');
        }
    }
    return 0;
}

980D - Perfect Groups

题解:

首先让我们检查完美的方块;一个完美的正方形是一个数字x,可以写成一个整数和它本身的乘积y * y。这意味着对于数字x的每个素数因子,该因子的频率必须是偶数,因此它可以在两个y中的每一个之间均匀分布。
对于一个组中的每两个数字a和b,对于一个素因子pi,或者a和b都具有偶数的pi频率,或者它们都具有奇数的频率。
因此,使用这种观察,对于阵列中的每个数字x,我们可以丢弃所有相同的素数因子对(每个因子以奇数频率保留一个副本)。
例如,数字40的因素是2,2,2,5,所以我们可以忽略第一对2,因为它们是冗余的,并将其转换为数字2,5,这是数字10。

现在,在用奇数因素的乘积替换每个数字后,我们可以计算每个子数组中不同元素的数量,因为每个元素只能与其副本一起分组。这可以通过检查所有可能的子阵列并保持频率数组来计算其中不同元素的数量来完成。
- 元素需要映射到1到n之间的非负整数,所以我们不用去使用一个集来对它们进行计数。
- 在子数组中存在零的情况下需要小心。零可以加入任何组,所以除非子数组只包含零,否则我们可以忽略它们。
复杂度:O(n×sqrt(maxai)+n2)

原版:First let us examine perfect squares; a perfect square is a number x that can be written as the product of an integer and itself yy. This means that for each prime factor of the number x, the frequency of that factor must be even so it can be distributed evenly between each of the two y's.This leads to the idea that for every two numbers a and b in a group, for a prime factor pi, either both a and b have an even frequency of pi, or they both have an odd frequency of it.So using that observation, for each number x in the array we can discard all pairs of equal prime factors (keeping one copy of each factor with an odd frequency).For example, number 40 has factors 2,2,2,5, so we can just ignore the first pair of 2s because they're redundant and transform it into 2,5, which is the number 10.

Now after replacing each number with the product of its odd factors, we can just count the number of distinct elements in each subarray as each element can be only grouped with its copies. This can be done by checking all possible subarrays and keeping a frequency array to count the number of distinct elements in it.

- Elements need to be mapped to non-negative integers between 1 and n so we don't use a set to count them.

- Need to be careful in case there's a zero in the subarray. Zeros can join any group, so unless the subarray contains only zeros, we can ignore them.    Solution Complexity: O(n×sqrt(maxai)+n2)

980E - The Number Games

As the final set of remaining districts need to be reachable from each other, this means that the resulting tree is a sub-graph of the original one.

Now, looking at the number of fans in each district, district i has 2i fans. This means that if we had a choice of including a district i in our solution and discarding all the districts with indices less than i then it'd be better than discarding district i and including all the others, as 2i=2i1+2i2+...+20+1.

This leads us to the following greedy solution:

Let's try to find which districts to keep instead of which to discard, let's first root the tree at district n, as we can always keep it, and go through the remaining districts by the order of decreasing index. Now at each step, if we can include district i into our solution by taking it and all of the nodes on the path connecting it to our current sub-graph, then we should surely do so, otherwise we can just ignore it and move on to the next district.

This can be implemented by building a parent sparse-table and using Binary Lifting at each district i to find the first of its ancestors that has been already included in our sub-graph. The distance to this ancestor represents the number of districts that need to be included in the games to have district i included. So if we can still include that many districts in our sub-graph then we will traverse through the path and mark them as included.     Solution Complexity: O(nlogn)

980F - Cactus to Tree

The following solution is implemented in 136 lines, but most of it is a simple BFS and two DFS functions for finding bridges and marking cycles, the main part of the solution is implemented in 38 lines. Please check the code after (or while?) reading if it is not clear.

Note that if we run a BFS from a node u, the BFS spanning tree will represent the edges that we should keep to minimize the answer for node u. So we actually need to find the maximum length out of all shortest paths that starts at u and end at every other node.

We will first focus on finding the answer for each node on one cycle:

For each node u on the cycle, we can compute L[u], the length of the longest shortest path that starts at node u and uses only the edges that do not belong to the cycle. This can be done using BFS in O(n+m) for one cycle. Using the computed values, we can find the final answer for all nodes on the cycle in O(klogk) , or O(k), where k is the number of nodes on the cycle.

For a node u, we need to find a node v on the cycle such that L[v]+distance(u,v) is maximized, where distance(u,v) is the length of the shortest path between u and v on the cycle. Therefore, the answer with regards to each node u will be the maximum between L[u] and L[v]+distance(u,v), for each node v in the same cycle as u.

We can do this using a heap and prefix sums idea as follows: loop for 2k iterations over the cycle nodes, in the ith iteration (0i<2k) add the value L[cycle[imodk]]+2ki to the heap with the time it was added in (time=2ki, time is decreasing), that is, add the pair (L[cycle[imodk]]+2ki,2ki). Now at a given iteration j, pop from the heap all top values added at time greater than 2kj+k/2, as distance(u,v) can't exceed k/2. Now assuming the top pair in the queue is (x,y), then x(2kj) is a possible answer for this node.

We need to do this again in counter-clockwise. Since we will visit each node four times, keep the maximum distance Zi

found for each node i in the cycle and the final answer for that node will be max(Li,Zi) .

Now if we have the answer for one cycle, when we move using an edge (a,b) to another cycle (or node), we only need to know one value to be able to solve the next cycle, that value is the maximum between Za and the length of the longest path that goes through bridges other than (a,b). This value is increased by 1 when passed since we will move through the edge (a,b).

Implementation:Marking the bridges will help in deciding if an edge will take us outside a cycle or not so we can compute Li. Also removing the bridges will make it easy to find which nodes form each cycle.

We can find any BFS spanning tree and use it to find the length of the longest path that starts at a node and uses a bridge first, note that this distance goes only down as the tree is rooted at the starting node, but the values Lu for every u in the first cycle will be correct so we can start with them.      Solution: https://ideone.com/EEORpR


                                                                                ——时间划过风的轨迹,那个少年,还在等你。

猜你喜欢

转载自blog.csdn.net/flora715/article/details/80451467