zoukankan      html  css  js  c++  java
  • Codeforces Round #662 (Div. 2) 题解

    比赛网址:https://codeforces.com/contest/1393

    A. Rainbow Dash, Fluttershy and Chess Coloring

    网址:https://codeforces.com/contest/1393/problem/A

    One evening Rainbow Dash and Fluttershy have come up with a game. Since the ponies are friends, they have decided not to compete in the game but to pursue a common goal.

    The game starts on a square flat grid, which initially has the outline borders built up. Rainbow Dash and Fluttershy have flat square blocks with size (1×1), Rainbow Dash has an infinite amount of light blue blocks, Fluttershy has an infinite amount of yellow blocks.

    The blocks are placed according to the following rule: each newly placed block must touch the built on the previous turns figure by a side (note that the outline borders of the grid are built initially). At each turn, one pony can place any number of blocks of her color according to the game rules.

    Rainbow and Fluttershy have found out that they can build patterns on the grid of the game that way. They have decided to start with something simple, so they made up their mind to place the blocks to form a chess coloring. Rainbow Dash is well-known for her speed, so she is interested in the minimum number of turns she and Fluttershy need to do to get a chess coloring, covering the whole grid with blocks. Please help her find that number!

    Since the ponies can play many times on different boards, Rainbow Dash asks you to find the minimum numbers of turns for several grids of the games.

    The chess coloring in two colors is the one in which each square is neighbor by side only with squares of different colors.

    Input

    The first line contains a single integer (T) ((1≤T≤100)): the number of grids of the games.

    Each of the next (T) lines contains a single integer (n) ((1≤n≤10^9)): the size of the side of the grid of the game.

    Output

    For each grid of the game print the minimum number of turns required to build a chess coloring pattern out of blocks on it.

    Example

    input

    2
    3
    4
    

    output

    2
    3
    

    Note

    For (3×3) grid ponies can make two following moves:

    image


    发现规律,直接敲代码。(提示:从每次的覆盖程度来分析较易)

    C ++ AC代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int n;
    int main()
    {
    	int T;
    	scanf("%d", &T);
    	while(T --)
    	{
    		scanf("%d", &n);
    		printf("%d
    ", n / 2 + 1);
    	}
    	return 0;
    }
    

    B. Applejack and Storages

    网址:https://codeforces.com/contest/1393/problem/B

    This year in Equestria was a year of plenty, so Applejack has decided to build some new apple storages. According to the advice of the farm designers, she chose to build two storages with non-zero area: one in the shape of a square and another one in the shape of a rectangle (which possibly can be a square as well).

    Applejack will build the storages using planks, she is going to spend exactly one plank on each side of the storage. She can get planks from her friend's company. Initially, the company storehouse has (n) planks, Applejack knows their lengths. The company keeps working so it receives orders and orders the planks itself. Applejack's friend can provide her with information about each operation. For convenience, he will give her information according to the following format:

    • (+x): the storehouse received a plank with length (x)
    • (−x): one plank with length x was removed from the storehouse (it is guaranteed that the storehouse had some planks with length (x)).
      Applejack is still unsure about when she is going to order the planks so she wants to know if she can order the planks to build rectangular and square storages out of them after every event at the storehouse. Applejack is busy collecting apples and she has completely no time to do the calculations so she asked you for help!

    We remind you that all four sides of a square are equal, and a rectangle has two pairs of equal sides.

    Input

    The first line contains a single integer (n) ((1≤n≤10^5)): the initial amount of planks at the company's storehouse, the second line contains n integers (a_1,a_2,…,a_n) ((1≤a_i≤10^5)): the lengths of the planks.

    The third line contains a single integer (q) ((1≤q≤10^5)): the number of events in the company. Each of the next (q) lines contains a description of the events in a given format: the type of the event (a symbol(+)or(−)) is given first, then goes the integer(x)((1≤x≤10^5)).

    Output

    After every event in the company, print "(YES)" if two storages of the required shape can be built from the planks of that company's set, and print "(NO)" otherwise. You can print each letter in any case (upper or lower).

    Example

    input

    6
    1 1 1 2 1 1
    6
    + 2
    + 1
    - 1
    + 2
    - 1
    + 2
    

    output

    NO
    YES
    NO
    NO
    NO
    YES
    

    Note

    After the second event Applejack can build a rectangular storage using planks with lengths (1, 2, 1, 2) and a square storage using planks with lengths (1, 1, 1, 1).

    After the sixth event Applejack can build a rectangular storage using planks with lengths (2, 2, 2, 2) and a square storage using planks with lengths (1, 1, 1, 1).


    维护两个量,一个是有一对一样的,一个是四个都一样的。然后,如若满足题意,首先要保证有正方形,其次再满足长方形。如果同种板子数量大于2,就加一,否则减一。(维护操作较复杂繁琐不再赘述啦)

    C ++ AC代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int SIZE = 1000000;
    int n, q, a[SIZE];
    int cnt[SIZE] = {}, d1 = 0, d2 = 0, val = -1;
    int main()
    {
    	scanf("%d", &n);
    	for(int i = 0; i < n; ++ i) scanf("%d", &a[i]);
    	for(int i = 0; i < n; ++ i) ++ cnt[a[i]], val = max(val, a[i]);
    	for(int i = 1; i <= val; ++ i) 
    	{
    		if(cnt[i] > 1) 
    		{
    			d2 += cnt[i] / 4;
    			d1 += (cnt[i] % 4) / 2;
    		}
    	}
    	scanf("%d", &q);
    	char op;
    	int tmp;
    	for(int i = 0; i < q; ++ i)
    	{
    		cin >> op >> tmp;
    		if(op == '-')
    		{
    			-- cnt[tmp];
    			if(cnt[tmp] / 4 == (cnt[tmp] + 1) / 4 - 1)
    			{
    				++ d1;
    				-- d2;
    			} else 
    			{
    				if(cnt[tmp] & 1) -- d1;
    			}
    		}
    		else
    		{
    			if((cnt[tmp] + 1) / 4 > cnt[tmp] / 4)
    			{
    				-- d1, ++ d2;
    			}
    			else
    			{
    				if(cnt[tmp] & 1) ++ d1;
    			}
    			++ cnt[tmp];
    		}
    		if(d2)
    		{
    			if(d1 > 1 || d2 > 1)
    			{
    				puts("YES");
    				continue;
    			}
    			puts("NO");
    			continue;
    		}
    		puts("NO");
    	}
    	return 0;
    }
    

    C. Pinkie Pie Eats Patty-cakes

    网址:https://codeforces.com/contest/1393/problem/C

    Pinkie Pie has bought a bag of patty-cakes with different fillings! But it appeared that not all patty-cakes differ from one another with filling. In other words, the bag contains some patty-cakes with the same filling.

    Pinkie Pie eats the patty-cakes one-by-one. She likes having fun so she decided not to simply eat the patty-cakes but to try not to eat the patty-cakes with the same filling way too often. To achieve this she wants the minimum distance between the eaten with the same filling to be the largest possible. Herein Pinkie Pie called the distance between two patty-cakes the number of eaten patty-cakes strictly between them.

    Pinkie Pie can eat the patty-cakes in any order. She is impatient about eating all the patty-cakes up so she asks you to help her to count the greatest minimum distance between the eaten patty-cakes with the same filling amongst all possible orders of eating!

    Pinkie Pie is going to buy more bags of patty-cakes so she asks you to solve this problem for several bags!

    Input

    The first line contains a single integer (T) ((1≤T≤100)): the number of bags for which you need to solve the problem.

    The first line of each bag description contains a single integer (n) ((2≤n≤10^5)): the number of patty-cakes in it. The second line of the bag description contains(n)integers(a_1,a_2,…,a_n)((1≤a_i≤n)): the information of patty-cakes' fillings: same fillings are defined as same integers, different fillings are defined as different integers. It is guaranteed that each bag contains at least two patty-cakes with the same filling.

    It is guaranteed that the sum of(n)over all bags does not exceed (10^5).

    Output

    For each bag print in separate line one single integer: the largest minimum distance between the eaten patty-cakes with the same filling amongst all possible orders of eating for that bag.

    Example

    input

    4
    7
    1 7 1 6 4 4 6
    8
    1 1 4 6 4 6 4 7
    3
    3 3 3
    6
    2 5 2 3 1 4
    

    output

    3
    2
    0
    4
    

    Note

    For the first bag Pinkie Pie can eat the patty-cakes in the following order (by fillings):(1, 6, 4, 7, 1, 6, 4)(in this way, the minimum distance is equal to(3)).

    For the second bag Pinkie Pie can eat the patty-cakes in the following order (by fillings):(1, 4, 6, 7, 4, 1, 6, 4)(in this way, the minimum distance is equal to(2)).


    这道题思想不复杂,但真的很好。我当时比赛看到这道题,一片空白,想要规划一下,发现顺序问题DP好像没办法解决。于是,我就开始逐步分析:如果元素都出现多次,那么最大距离是几??如果只有一个的话,两个量离得越远越好。还是不明白,不过观察到了一个小结论。如果事先我们把“重复”元素排好序,剩下的单元素能平摊就平摊,这会保证距离最大。然后呢,这个思想影响了我对于排序的理解。回到第一个问题,如果有大于等于二个重复元素,那么越平摊越好,这样如果再有单元素,我们直接把这些单元素平均分配即可。考虑出现次数最多的元素。让其他元素“插”在两个该元素的中间,并且每个元素空只“插”一个,从而保证最小距离一定不会超过两个该元素的最小距离。

    通过上面的分析,我们以下的解法:

    • 找出出现次数最多的元素(如若多个把它们视为一组);
    • 剩下的元素平摊即可。

    C ++ AC代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int maxn = 200000 + 5;
    int n, a[maxn], num[maxn];
    int main()
    {
    	int T, vmax;
    	scanf("%d", &T);
    	while(T --)
    	{
    		scanf("%d", &n);
    		vmax = 0;
    		memset(num, 0, sizeof(num));
    		for(int i = 1; i <= n; ++ i) 
    		{
    			scanf("%d", &a[i]);
    			vmax = max(vmax, a[i]);
    			++ num[a[i]];
    		}
    		int t = 0;int cnt = 0;
    		for(int i = 1; i <= vmax; ++ i)
    		{
    			if(num[i] == t)
    			{
    				++ cnt;
    			} else if(num[i] > t)
    			{
    				t = num[i];
    				cnt = 1;
    			}
    		}
    		int r = n - cnt * t;
    		t --;
    		-- cnt;
    		printf("%d
    ", cnt + r / t);
    	}
    	return 0;
    }
    

    D. Rarity and New Dress

    网址:https://codeforces.com/contest/1393/problem/D

    Carousel Boutique is busy again! Rarity has decided to visit the pony ball and she surely needs a new dress, because going out in the same dress several times is a sign of bad manners. First of all, she needs a dress pattern, which she is going to cut out from the rectangular piece of the multicolored fabric.

    The piece of the multicolored fabric consists of (n×m) separate square scraps. Since Rarity likes dresses in style, a dress pattern must only include scraps sharing the same color. A dress pattern must be the square, and since Rarity is fond of rhombuses, the sides of a pattern must form a (45∘) angle with sides of a piece of fabric (that way it will be resembling the traditional picture of a rhombus).

    Examples of proper dress patterns:

    image

    Examples of improper dress patterns:

    image

    The first one consists of multi-colored scraps, the second one goes beyond the bounds of the piece of fabric, the third one is not a square with sides forming a (45∘) angle with sides of the piece of fabric.

    Rarity wonders how many ways to cut out a dress pattern that satisfies all the conditions that do exist. Please help her and satisfy her curiosity so she can continue working on her new masterpiece!

    Input

    The first line contains two integers (n) and (m) ((1≤n,m≤2000)). Each of the next (n) lines contains (m) characters: lowercase English letters, the (j)-th of which corresponds to scrap in the current line and in the (j)-th column. Scraps having the same letter share the same color, scraps having different letters have different colors.

    Output

    Print a single integer: the number of ways to cut out a dress pattern to satisfy all of Rarity's conditions.

    Examples

    input

    3 3
    aaa
    aaa
    aaa
    

    output

    10
    

    input

    3 4
    abab
    baba
    abab
    

    output

    12
    

    input

    5 5
    zbacg
    baaac
    aaaaa
    eaaad
    weadd
    

    output

    31
    

    Note

    In the first example, all the dress patterns of size (1) and one of size (2) are satisfactory.

    In the second example, only the dress patterns of size (1) are satisfactory.


    这道题其实是在吓唬人的。

    最开始我们希望通过枚举图形中心求解。会发现这会有很多问题。(譬如后效性问题)
    我们可以考虑DP,只不过需要DP四次。答案就是这四次DP的最小值(累和即可)。

    C ++ AC代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int SIZE = 2000 + 5;
    int n, m, d1[SIZE][SIZE], d2[SIZE][SIZE], d3[SIZE][SIZE], d4[SIZE][SIZE], ans = 0;
    char map[SIZE][SIZE];
    int main()
    {
    	scanf("%d %d", &n, &m);
    	memset(map, '0', sizeof(map));
    	for(int i = 1; i <= n; ++ i)
    		for(int j = 1; j <= m; ++ j)
    			d1[i][j] = d2[i][j] = d3[i][j] = d4[i][j] = 1;
    	
    	for(int i = 1; i <= n; ++ i) scanf("%s", (map[i] + 1));
    	for(int i = 1; i <= n; ++ i)
    	{
    		for(int j = 1; j <= m; ++ j)
    		{
    			if(map[i][j] == map[i - 1][j] && map[i][j] == map[i][j - 1])
    			{
    				d1[i][j] = min(d1[i - 1][j], d1[i][j - 1]) + 1;
    			}
    		}
    	}
    	for(int i = 1; i <= n; ++ i)
    	{
    		for(int j = m; j; -- j)
    		{
    			if(map[i][j] == map[i - 1][j] && map[i][j] == map[i][j + 1])
    			{
    				d2[i][j] = min(d2[i - 1][j], d2[i][j + 1]) + 1;
    			}
    		}
    	}
    	for(int i = n; i; -- i)
    	{
    		for(int j = 1; j <= m; ++ j)
    		{
    			if(map[i][j] == map[i + 1][j] && map[i][j] == map[i][j - 1])
    			{
    				d3[i][j] = min(d3[i + 1][j], d3[i][j - 1]) + 1;
    			}
    		}
    	}
    	for(int i = n; i; -- i)
    	{
    		for(int j = m; j; -- j)
    		{
    			if(map[i][j] == map[i + 1][j] && map[i][j] == map[i][j + 1])
    			{
    				d4[i][j] = min(d4[i + 1][j], d4[i][j + 1]) + 1;
    			}
    		}
    	}
    	for(int i = 1; i <= n; ++ i)
    		for(int j = 1; j <= m; ++ j)
    			ans += min(min(d1[i][j], d3[i][j]), min(d2[i][j], d4[i][j]));
    	printf("%d
    ", ans);
    	return 0;
    }
    

    总结

    本场比赛状态比较稳定,正常水平,如C,我从约束最多的情况入手,逐步逼近最终成功,这启发每见到一道没有思路的题目,应从特殊情况入手思考正解。另外,对于D题,我通过对非正解的方法的理解推得正确的解题思路。这都会归功于比赛专注、心稳。

  • 相关阅读:
    Ultra-QuickSort(归并排序求逆序对数)
    Power Network (最大流增广路算法模板题)
    Sorting It All Out
    Asteroids(二分图最大匹配模板题)
    昂贵的聘礼
    Borg Maze(bfs+prim)
    Currency Exchange(判断是否有正环)
    Children of the Candy Corn (bfs+dfs)
    Tautology
    Flip Game
  • 原文地址:https://www.cnblogs.com/zach20040914/p/13523535.html
Copyright © 2011-2022 走看看