ACM1008: Horcrux

Description

A Horcrux is an object in which a Dark wizard or witch has hidden a fragment of his or her soul for the purpose of attaining immortality. Constructing a Horcrux is considered Dark magic of the foulest, most evil kind, as it violates laws of nature and morality, and requires a horrific act (a.k.a. murder) to accomplish.

There are two kinds of horcruxes, the white one, denoted as , and the black one, denoted as . Topper has got N horcruxes, and he wants to destroy them to win the Dark wizard. Toper places all the horcruxes in a line from left to right, one by one, and then says a magic spell to destroy them. In order to make the magic spell works, Toper needs to know the number of the white horcruxes.

Since the horcruxes also has magic, when placing the horcruxes, they will change color from white to black or from black to white under the following rules:

  1. When Topper places the i-th horcrux and i is an even number: If the i-th horcrux and the rightmost horcrux have different colors, all consecutive horcruxes of the same color on the right change its color.

  2. In other situations, no magic works.

For example, suppose the horcruxes on the line are:

△△▲▲△△△

After placing 7 horcruxes.

If the 8-th horcrux is white, since its color and the color of the rightmost horcrux are the same. Therefore, the horcruxes on the line become as follows:

△△▲▲△△△△

If the 8-th horcrux is black, since its color and the color of the rightmost horcrux are different, the 3 consecutive white stones on the right change their color. Therefore, the stones on the line become as follows:

△△▲▲▲▲▲▲

You see, it’s not an easy job to beat the Dark wizard. So write a program to help Topper.

Input

There are some test cases. In each test case, the first line contains a positive integer n (1≤n≤100,000), which is the number of horcruxes. The following n lines denote the sequence in which Topper places the horcruxes. 0 stands for white horcrux, and 1 stands for black horcrux.

Output

For each test case, output one line containing only the number of white horcruxes on the line after Topper places n horcruxes.

Sample Input

8
1
0
1
1
0
0
0
0
8
1
0
1
1
0
0
0
1

Sample Output

6
2

这道题很坑,我开始想了一个想法,能够写出来,但是由于时间超时,只能想第二种方法。

最初始的想法:

首先用户输入一个数字,决定你的10的个数。我定义了一个数组,用来存储所有的1和0,然后开始遍历这个数组。

遍历的时候,当我们访问到他的序号为偶数且与前面一个的数字不同时,开始执行翻转。我们访问到这个数字时,再从他开始往前访问,直到访问到与他数字相同或者序号为0时结束,然后将这中间的颜色全部变为与这个偶数序号的颜色一致,最后再找出0的个数即可。但是在这里,我们用了多次循环,效率很低,可能导致了时间超出,于是我进行了改进。

新思路:

同样也是定义一个数组用来存储所有的0和1,但是我们遍历之后的操作发生了改变,我们从序号0开始,用一个结构数组来存储。结构第一项为连续的颜色,第二项为连续的个数。这样我们就只需要记录0连续了多少个,或者是1连续了多少个。同样,当访问到偶数项且与前面一个不同时,我们只需要将前面连续的颜色变为该偶数项的颜色,数量要加上一个,并且再与之前的那一组(若存在)连续的数量合二为一。例如:我们首先有连续4个黑,然后有连续3个白,这时候第八个为黑,那么3个白将变为三个黑,数量为4+3+1即可。

代码如下

/*结果是对的,但是超时了 
#include <iostream>
using namespace std ;

void playHorcrux(int length){
	int s[length];
	int count; 
	int number = 0;
	for(int i = 0; i < length; i++){
		cin>>s[i];
		if(i % 2 == 1 && s[i] != s[i - 1]){
			for(int j = i - 1; j >= 0; j--){
				if(s[i] == s[j]){
					count = j;
					break;
				}
				else if(j == 0){
					count = 0;
				}
			}
			for(int j = i - 1; j >= count; j--){
				s[j] = s[i];
			}
		}
	}
	for(int i = 0; i < length; i++){
		if(s[i] == 0){
			number = number + 1;
		}
	} 
	 cout<<number<<endl;
}

int main(){
    int num;
	while((cin>>num))
	{
		playHorcrux(num);
	}
	return 0;
}*/

//改进版本
#include <stdio.h> 
#define M 100005
struct soul{
    int color,num;
}a[M];
int main()
{
    int n, ans, count;
    while(~scanf("%d", &n))
    {
        count = 0;
        scanf("%d", &ans);
        a[count].color = ans;
        a[count].num = 1;
        for(int i = 2; i <= n; i++)
        {
            scanf("%d", &ans);
            if(ans == a[count].color)
                a[count].num++;
            else
            {
                if(i&1) 
                {
                    count++;
                    a[count].color = ans;
                    a[count].num = 1;
                }else
                {
                    a[count].num++;
                    a[count].color = ans;
                    if(count > 0)
                    {
                        a[count-1].num += a[count].num;
                        count--;
                    }
                }
            }
        }
        ans = 0;
        for(int i = 0; i <= count; i++)
            if(a[i].color == 0)
            ans += a[i].num;
        printf("%d\n", ans);
    }
    return 0;
}
 

前面为之前的想法,后面的是改进的,如果可以简化代码改善时间限制的欢迎评论。

猜你喜欢

转载自blog.csdn.net/qq_41681675/article/details/81234861
ACM