zoukankan      html  css  js  c++  java
  • zoj3961(区间问题)

    点击打开zoj1961Let's Chat

    Time Limit: 1 Second      Memory Limit:65536 KB

    ACM (ACMers' Chatting Messenger) is a famous instant messaging software developed by Marjar Technology Company. To attract more users, Edward, the boss of Marjar Company, has recently added a new feature to the software. The new feature can be described as follows:

    If two users, A and B, have been sending messages toeach other on the lastmconsecutive days, the "friendship point" between them will be increased by 1 point.

    More formally, if user A sent messages to user B on each day between the (i -m + 1)-th day and thei-th day (both inclusive), and user B also sent messages to user A on each day between the (i - m + 1)-th day and thei-th day (also both inclusive), the "friendship point" between A and B will be increased by 1 at the end of thei-th day.

    Given the chatting logs of two users A and B duringn consecutive days, what's the number of the friendship points between them at the end of then-th day (given that the initial friendship point between them is 0)?

    Input

    There are multiple test cases. The first line of input contains an integerT (1 ≤T ≤ 10), indicating the number of test cases. For each test case:

    The first line contains 4 integers n (1 ≤n ≤ 109),m (1 ≤mn),x andy (1 ≤x,y ≤ 100). The meanings ofn andm are described above, whilex indicates the number of chatting logs about the messages sent by A to B, andy indicates the number of chatting logs about the messages sent by B to A.

    For the following x lines, thei-th line contains 2 integersla,i andra,i (1 ≤la,ira,in), indicating that A sent messages to B on each day between thela,i-th day and thera,i-th day (both inclusive).

    For the following y lines, thei-th line contains 2 integerslb,i andrb,i (1 ≤lb,irb,in), indicating that B sent messages to A on each day between thelb,i-th day and therb,i-th day (both inclusive).

    It is guaranteed that for all 1 ≤ i <x,ra,i + 1 <la,i + 1 and for all 1 ≤i <y,rb,i + 1 <lb,i + 1.

    Output

    For each test case, output one line containing one integer, indicating the number of friendship points between A and B at the end of then-th day.

    Sample Input

    2
    10 3 3 2
    1 3
    5 8
    10 10
    1 8
    10 10
    5 3 1 1
    1 2
    4 5
    

    Sample Output

    3
    0
    

    Hint

    For the first test case, user A and user B send messages to each other on the 1st, 2nd, 3rd, 5th, 6th, 7th, 8th and 10th day. Asm = 3, the friendship points between them will be increased by 1 at the end of the 3rd, 7th and 8th day. So the answer is 3.


    Author: WENG, Caizhi
    Source: The 14th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple


    本题是:扫描线思想

    对于此类题需要注意:

       一:可能有区间合并

       二:可能有区间排序

       三:可能有不合法区间

       四:对于判断交区间,并不需要很多个if语句判断,具体的,

    我们设L=max(a.l,b.l),R=min(a.r.b.r),则做差为并期间,当R-L>0时为我们常见的具体的并区间。

    幸运的是本题良心题,不需要排序合并,而且数据小,即便O(xy)也能过

    //我的原始代码,拒绝不思考就引用
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    using namespace std;
    int n,m,x,y,ans;
    int l1[105],r1[105],l2[105],r2[105];
    void _in()
    {
    	cin>>n>>m>>x>>y;
    	for(int i=1;i<=x;i++)
    	 cin>>l1[i]>>r1[i];
    	for(int i=1;i<=y;i++)
    	 cin>>l2[i]>>r2[i];
    }
    void _find(int a,int b)
    {
    	int temp,L,R;
    	L=max(l1[a],l2[b]);
    	R=min(r1[a],r2[b]);
    	temp=R-L+1;
    	if(temp>=m) ans+=temp-m+1;
    }
    void _solve()
    {
    	for(int i=1;i<=x;i++)
    	 for(int j=1;j<=y;j++){
    	     _find(i,j);   
    	 }
    	 cout<<ans<<endl;
    }
    int main()
    {
    	int t,T;
    	cin>>T;
    	for(t=1;t<=T;t++){
    		ans=0;
    		_in();
    		_solve();
    	}
    	return 0;
    }

    理解起来应该很简单



    引申一下,对于这一类扫描线思想题目。

    我们的大概步骤是:

         1,排序(假定按左a.l为关键词排序)

         2,合并(如区间[1,3],[3,5]合并成[1,5].而[1,3],[2,4]合并成[1,4])

        3,按右a.r为关键词向右扫描,则本题的复杂度可以降到O(x+y) (应用师兄的代码http://blog.csdn.net/DongChengRong/article/details/70496302)

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=100+20;
    int n,m,x,y;
    
    struct Node
    {
        int start,endd;
    }A[maxn],B[maxn];
    
    /*int cmp(struct Node s1,struct Node s2)
    {
        return s1.start<s2.start;
    }*/
    
    int main()
    {
        int test;
        scanf("%d",&test);
        for(int i=0;i<test;i++)
        {
            scanf("%d%d%d%d",&n,&m,&x,&y);
            for(int j=1;j<=x;j++) scanf("%d%d",&A[j].start,&A[j].endd);
            for(int j=1;j<=y;j++) scanf("%d%d",&B[j].start,&B[j].endd);
            //sort(A+1,A+1+x,cmp);
            //sort(B+1,B+1+y,cmp);
            int ans=0,j=1,k=1;
            while(k<=y && j<=x)
            {
                int a,b;
                if(B[k].start>A[j].endd) { j++; continue; }
                if(B[k].endd<A[j].start) { k++; continue; }
                a=max(B[k].start,A[j].start);
                b=min(B[k].endd,A[j].endd);
                if(a>n || b>n) break;
                int date=b-a+1;
                int point=date+1-m;
                if(point>=1) ans+=point;
                if(A[j].endd<B[k].endd) j++;
                else if(A[j].endd==B[k].endd) { j++; k++;}
                else k++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    (当然,本题任然不需要排序)



    如有错误,感谢指出

  • 相关阅读:
    使用某些 DOCTYPE 时会导致 document.body.scrollTop 失效
    VB.NET 笔记1
    知识管理系统Data Solution研发日记之一 场景设计与需求列出
    知识管理系统Data Solution研发日记之五 网页下载,转换,导入
    折腾了这么多年的.NET开发,也只学会了这么几招 软件开发不是生活的全部,但是好的生活全靠它了
    分享制作精良的知识管理系统 博客园博客备份程序 Site Rebuild
    知识管理系统Data Solution研发日记之四 片段式数据解决方案
    知识管理系统Data Solution研发日记之二 应用程序系列
    知识管理系统Data Solution研发日记之七 源代码与解决方案
    知识管理系统Data Solution研发日记之三 文档解决方案
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7603984.html
Copyright © 2011-2022 走看看