My program is to solve the simple problem in the Link[http://codeforces.com/problemset/problem/143/A]
#include <stdio.h>
    #include <cstring>
    #include <math.h>
    #include<set>
    #include<iostream>
    #include<algorithm>
    #define MAXN 25
    #define INF 100000000
    using namespace std;
    struct _point
    {
        int L;int r;
        bool operator<(const _point &a)const{
        return (this->L<a.L);
        }
    };
    set<_point>  up,down;

    int r1,r2,c1,c2,d1,d2;

    void solve(){
           _point tmp;
        for(int i=0;i<(r1+1)/2;i++){
            cin>>tmp.L;cin>>tmp.r; up.insert(tmp);
           }
        for(int i=0;i<(r2+1)/2;i++){
            cin>>tmp.L>>tmp.r;down.insert(tmp);
           }
        set<_point>::iterator it_up=up.begin();
        set<_point>::iterator it_down=down.begin();
        for(it_up=up.begin();it_up!=up.end();it_up++){
           //------------Problem is in the next line(it_down++)------------
            for(it_down=down.begin();it_down!=down.end();it_down++){
           //-------------------------------------------------------------         
                if((*it_up).L+(*it_down).L!=c1||(*it_up).r+(*it_down).r!=c2||(*it_up).r+(*it_down).L!=d2||(*it_up).L+(*it_down).r!=d1) {
                    up.erase(*it_up),down.erase(*it_down);
                }
            }
        }
        it_up=up.begin(),it_down=down.begin();
        if(!up.empty()&&!down.empty()){
            cout<<(*it_up).L<<" "<<(*it_down).r<<endl;
            cout<<(*it_down).L<<" "<<(*it_down).r<<endl;
        }
        else cout<<-1<<endl;
    }
    int main()
    {
       freopen("input.txt","r",stdin);
      freopen("output.txt","w",stdout);
       while(cin>>r1>>r2>>c1>>c2>>d1>>d2) solve();
        return 0;
    }
 Thanks for your HELP,sincerely!

Recommended Answers

All 6 Replies

What does it do that you think it shouldn't do, or what does it not do that you think it should do? You have to say more than "here is a problem".

As an aside, you're including C headers for which there are modern C++ replacement version, and some of the headers you're including you aren't actually using. This being the future, consider using C++ file opening functions rather than C. The use of variable name of one character is a very bad idea; if your variable names were meaningful, it would help you program and it would help other people understand what you're trying to do.

Thanks for your advice.
Sorry as I should have made my question clear.
Well,when I debugged my program , the error came as the pictures show.
I have no idea how to deal with it.

If I had to guess, you're changing the containers down and up, and in doing so invalidating iterators.

When you call erase on an iterator in a set, you invalidate that iterator.

Here's a quote from a standard, but I don't recall if this is from C++98 or C++03 or C++11. It gives the general idea, anyway.

Standard 23.1.2.8

... the erase members shall invalidate only iterators and references to the erased elements.

So in line 37 above, when you call erase on the iterators, you can never use those iterators again. So you can't call ++ on them.

If you're using C++11, the erase function returns a new iterator that points to the next element, which you can make use of.

As a rule of thumb, if you change a container, double-check your code to ensure that any iterators to that container you have are still valid. This will require reading the references on the erase function for that container type, which should tell you which iterators will be invalidated.

The first issue is your comparison operator is not folowing the strict weak ordering that std::set requires. You are only comparing L when you need to check if the L's are equal and if they are then comapre against r.

bool operator<(const _point &a)const
{
    if (L == a.L)
        return r < a.r;
    return L < a.L;
}

The second issue you have is that erase() invalidates the iterators since they point to the location you erased. If you are going to erase like this you will need two other iterators to point to the next item in each set. then after the erase you can assign those pointer back to the ones you just erased.

if((*it_up).L+(*it_down).L!=c1||(*it_up).r+(*it_down).r!=c2||(*it_up).r+(*it_down).L!=d2||(*it_up).L+(*it_down).r!=d1) 
{
    set<_point>::iterator up_temp = std::next(it_up);
    set<_point>::iterator down_temp = std::next(it_down);
    up.erase(*it_up);
    down.erase(*it_down);
    it_up = up_temp;
    it_down = down_temp;
}

All right,it works.Thank you.

If you've got a modern compiler, you can directly use the returned value from the erase function.

if((*it_up).L+(*it_down).L!=c1||(*it_up).r+(*it_down).r!=c2||(*it_up).r+(*it_down).L!=d2||(*it_up).L+(*it_down).r!=d1) 
{
    set<_point>::iterator up_temp = std::next(it_up);
    set<_point>::iterator down_temp = std::next(it_down);
    it_up = up.erase(*it_up);
    it_down = down.erase(*it_down);
}

Don't forget that if you do erase an element, and your iterator has then moved on to the next element, applying ++ in the loop header will mean you skip an element.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.