zoukankan      html  css  js  c++  java
  • zoj 3197 Google Book

    这道题告诉我想法正确是多么重要,先是我自己想的时候没考虑到最后的页码作为循环的终止,我一直以区间个数来终止循环,这是多么愚蠢啊!然后,我看了别人的代码,但是很不幸超时了!

    我自己wa的代码,我感觉很正确就是对不了!

    
    
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    int cmp(const void *a,const void *b)
    {
    	return (*(int *)a-*(int *)b);
    }
    
    int main(void)
    {
    	int t,n,i,j,count,k,temp;
    	int s[5002][2];
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d",&n);
    		for(i=0;i<n;i++)
    		scanf("%d%d",&s[i][0],&s[i][1]);
    		qsort(s,n,sizeof(s[0]),cmp); 
    		count=0;
    		for(i=0,k=1;i<n&&k<n;)
    		{
    			if(s[i][1]>=s[k][1])/*盖住后面的 */
    			{
    				k++;
    				count++;
    			}
    			else if(s[i][0]==s[k][0]&&s[i][1]<=s[k][1])/*被后面盖住 */
    			{
    				/*如果i被k盖住,说明中间的全部被覆盖了*/ 
    				i=k;/*k后移一位,i移到k位置*/
    				k++;
    				count++;
    			}
    			else 
    			{
    				i=k;/*k后移一位,i移到k位置*/
    				k++;
    			}
    		}
    		printf("%d
    ",n-count);
    		
    	} 
    	return 0;
    }
     

    然后我就看网上的算法,然后改了,不过居然超时了

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    int cmp(const void *a,const void *b)
    {
        return (*(int *)a-*(int *)b);
    }
    int s[5001][2];
    int main(void)
    {
        int t,n,i,j,count,k,temp,end,sta,sum,ma;
        
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            
            for(i=0;i<n;i++)
            scanf("%d%d",&s[i][0],&s[i][1]);
            
            qsort(s,n,sizeof(s[0]),cmp); 
            ma=0;
            end = s[0][1],sta = s[0][0];/*得到比较的开始,和结束地址 */
             sum = 1;/*区间个数从1开始 */
            i = 1;          
             while(i<n && s[i][0]  == sta)/*找到以1为开始区间群中最大那一页页码 */         
             {         
                 if(end < s[i][1]) {             
                          end = s[i][1];        
                         ma=i;         
                         }     ;
                        i++;      
                      }
                      while(end!=n)/*当找到的页码等于最后的页码就可以停止循环 */
                      {
                          j=s[ma][1];/*得到当前以i为开始区间群中最大的页码 */
                              sta = end+1;/*查找的页码从上一个区间群中的最后一个开始 */
                              i++;/*获取当前区间群的第一个 */
                              while(i<n && s[i][0] <= sta)/*找打这个区间群中最大的 j*/    
                              {
                                      if(s[i][1] > j) 
                                      {
                                          j = s[i][1];
                                          ma=i;
                                      }
                                      i++;
                              }
                              if(j > end)/*如果区间群中最大的大于上一个区间群的最大,那么就需要增加一个了 */
                              {
                                     sum++;
                                     end = j;
                              }
                      }
                      printf("%d
    ",sum);
            
        } 
        return 0;
    }

    最后实在没办法了,只能再找了,终于看到了一个最ok的了,就是在已经排好的区间中找多少个尾部递增序列,很轻松的解决了这题,我靠怎么都没想过这种方法!想法正确真的很重要

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    int cmp(const void *a,const void *b)
    {
        return (*(int *)a-*(int *)b);
    }
    int s[5001][2];
    int main(void)
    {
        int t,n,i,j,end,sta,sum,p,max;
        
        scanf("%d",&t);
        
       while(t--)
        {
            scanf("%d",&end);/*最后的页码号*/
            
            for(i=0;i<end;++i)
            {
                scanf("%d %d",&s[i][0],&s[i][1]);
            }
            
            qsort(s,end,sizeof(s[0]),cmp);
            
            n=0 ;
            p=0 ;
            sum=1 ;
            
            while(sum<=end)
            {
                
                max=-1 ;/*每一次求新递增序列的最大值,这个值就需要初始化*/
                
                for(i=p;i<end;++i)/*循环页码区间,找到连续递增最大的页码*/ 
                {
                    if(s[i][0]<=sum)
                    {
                        if((s[i][1]>=sum)&&(s[i][1]>max))/*更新最大的页码*/
                        {
                            max=s[i][1] ;
                        }
                    }
                    else /*如果页码递减就跳出*/
                     break ;
                }
                
                sum=max+1 ;/*在后面递增区间中找出比前一个递增最大值,大1的页码*/ 
                p=i ;/*跳到最大区间后面*/ 
                ++n ;/*每一次找新递增序列的最大,就代表前面序列区间内查最大的就可以了,所以加1*/ 
            }
            
            printf("%d
    ",n);
            
        } 
        return 0;
    }
  • 相关阅读:
    下载并安装chrome插件的方法
    QString转化为char *的方式
    a socket demo
    TCP/IP相关知识总结(马士兵教育)视频对应图片
    C++中的按位或的用意
    dll路径加载顺序
    【第二周】【作业七】四人小组项目
    【第二周】【作业六】结对项目,四则运算++
    【第二周】【作业八】个人项目词频统计++
    【第二周】【作业三】效能测试
  • 原文地址:https://www.cnblogs.com/woshijishu3/p/3602860.html
Copyright © 2011-2022 走看看