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;
    }
    (当然,本题任然不需要排序)



    如有错误,感谢指出

  • 相关阅读:
    [zz]Ubuntu源签名错误/Ubuntu 更新源签名错误 –BADSIG 40976EAF437D05B5
    [zz]GNU C __attribute__ 机制简介
    [zz]为小米创建虚拟机路由器
    liburcu 库
    多代理集群调度:可伸缩性和灵活性
    automake的使用速查
    automake之简单的例子
    ajax原生
    Cookie 和Session 的原理
    路径问题
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7603984.html
Copyright © 2011-2022 走看看