13.7.31 Wed C(模拟)

本文介绍了一种在指定区间内进行颜色填充的问题,并提供了一种简单直观的解决方案。通过对每段区间的颜色进行覆盖,最终统计可见颜色的数量及分布。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      C - C

Description

Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones.

Your task is counting the segments of different colors you can see at last.

Input

The first line of each data set contains exactly one integer n, 1 <= n <= 8000, equal to the number of colored segments.

Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:
x1 x2 c
x1 and x2 indicate the left endpoint and right endpoint of the segment, c indicates the color of the segment.

All the numbers are in the range [0, 8000], and they are all integers.

Input may contain several data set, process to the end of file.

Output

Each line of the output should contain a color index that can be seen from the top, following the count of the segments of this color, they should be printed according to the color index.

If some color can't be seen, you shouldn't print it.

Print a blank line after every dataset.

Sample Input

5
0 4 4
0 3 1
3 4 2
0 2 2
0 2 3
4
0 1 1
3 4 1
1 3 2
1 3 1
6
0 1 0
1 2 1
2 3 1
1 2 0
2 3 0
1 2 1

Sample Output

1 1
2 1
3 1

 

1 1

 

0 2
1 1

  题意:

  在n个区间中填色,x1代表起点,x2代表终点,c代表颜色的名字(或者说第c种颜色),填的颜色后面的可以覆盖前面的,求最后可看到的颜色一共被分成几段。

  思路:

  用数组模拟染色的情况,从 [ X1 , X2 )(X1是可取的,X2是不可取的),每次从下标为X1循环到X2-1,都赋值为这次要染的颜色的名字。最后通过判断每个数字有多少截就能对应输出相应的颜色有多少截了。

Wrong and test:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int main()
{
	int N,color,from,to,i,sum,max,j,temp;
	int number[8005];
        int co[8005]; 

	while(scanf("%d",&N)!=EOF)
	{
	 memset(number,0,sizeof(number));
	 memset(co,0,sizeof(co));
	 max=0;
	 i=0;
	 while(N--)
	 {
	  scanf("%d%d%d",&from,&to,&color);
	  if(to>max) max=to;
	  for(from;from<to;from++)
	  {
	  	number[from]=color;
	  }
	  co[i++]=color;  	
   	 }
	sum=i;  //一开始忘了sum的初始化
	sort(co,co+sum);
	number[max]=-1;
	max++;

//测试数据	
//	printf("\nThe number's color is:\n");
//	for(i=0;i<max;i++)
//		printf("%d ",number[i]);
//	printf("\n");
//	system("pause");
	
//	printf("\nThe color is:\n");
//	for(i=0;i<sum;i++)
//	 printf("%d ",co[i]);
//	  printf("\n");
//	system("pause");
	
     temp=0;
	 for(j=1;j<max;j++)
      if(number[j]!=co[0]&&number[j-1]==co[0]) temp++;
      if(temp) printf("%d %d\n",co[0],temp);
	 
	 for(i=1;i<sum;i++)
     {
    	temp=0;
    	if(co[i]!=co[i-1])
    	{
    		for(j=1;j<max;j++)
            if(number[j]!=co[i]&&number[j-1]==co[i]) temp++;
            if(temp) printf("%d %d\n",co[i],temp);
    	}
     }
     
     if(i==sum) printf("\n");
    }
}


错误说明:
1.当例子为
5
1 3 0
2 3 0
1 2 1
5 6 3
3 5 2
的时候,模拟的线段应该是(0)1 0 2 2 3但是1前面还有个0,这个0是初始化的时候设置的,所以这里存在着盲点,所以要将颜色的0和初始化的0区分开,用颜色-1来代表0;
2.还有每个CASE之间要空一行;
3.填完色后要在最后加个-1(因为判断number[j]!=co[i]&&number[j-1]==co[i]是后一个与前一个对比判断的,所以为了保证最后一个数能被判断到,所以要最后加个-1。

    AC:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int main()
{
	int N,color,from,to,i,sum,max,j,temp;
	int number[8005];
    int co[8005]; 

	while(scanf("%d",&N)!=EOF)
	{
	memset(number,0,sizeof(number));
	memset(co,0,sizeof(co));
	max=0;
	i=0;
	 while(N--)
	 {
	  scanf("%d%d%d",&from,&to,&color);
	  if(to>max) max=to;
	  for(from;from<to;from++)
	  {
	  	  if(color==0) number[from]=-1;
		  else number[from]=color;
	  }
	  if(color==0) co[i++]=-1;
	  else co[i++]=color;  	
   	 }
	sum=i;
	sort(co,co+sum);
	number[max]=-10;
	max++;
	
     temp=0;
	 for(j=1;j<max;j++)
      if(number[j]!=co[0]&&number[j-1]==co[0]) temp++;
      if(temp) 
	  			{
                  if(co[0]==-1) printf("%d %d\n",co[0]+1,temp);
				  else printf("%d %d\n",co[0],temp);
      			}
	 for(i=1;i<sum;i++)
     {
    	temp=0;
    	if(co[i]!=co[i-1])
    	{
    		for(j=1;j<max;j++)
            if(number[j]!=co[i]&&number[j-1]==co[i]) temp++;
            if(temp) 
			{
			 if(co[i]==-1) printf("%d %d\n",co[i]+1,temp);
			 else printf("%d %d\n",co[i],temp);
    	    }
		}
     }
     if(i==sum) printf("\n");
    }
}

   总结:

   当时比赛的时候,连题目都不敢看,因为坚信自己是做不出来的。今天要不是师兄叫我再看下这题的话,我估计还不敢做这题。虽然不是用线段树做的,而且神奇的做出来之后才知道这是暴力。分析时间复杂度,然后根据时间来选择最适合最快速的方法解决题目真的很重要,又学到东西了。因为练得实在太少了,没有实力就没有信心,没有信心就没有勇气去坚持完一场比赛。这道题还需要用线段树来做一遍(迟点再添加),虽然这样子水过去了,但是还是有点不太踏实。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值