noip模拟赛 柜(暴力)

分析:暴力的方法是非常显然的,从起点走一次,从终点走一次,路径相交的点即为所求,但是这样存图都很难存下,而且如果数据极端可能要求R*C次,时间空间都受不了.如果不需要记录整张图,并且一次能移动很多步就好了,标程用了树状数组+set,我不是很懂,只能打一个暴力了.

暴力:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
const int maxn = 10010;
const int dx[] = { 0, 0, 1, -1 }; 
const int dy[] = { 1, -1, 0, 0 };
int n, m, A, B, ansx, ansy, cnt;
bool vis[maxn][maxn]; //512M的内存这数组应该是极限了.
int a[maxn][maxn];

struct node
{
    int x, y;
}e[maxn];

bool cmp(node a, node b)
{
    if (a.x == b.x)
        return a.y < b.y;
    return a.x < b.x;
}

void solve1()
{
    int x = 1, y = 1, dir = 0;
    while (1)
    {
        if (a[x][y] == 1)
            dir = 3 - dir;
        if (a[x][y] == 2)
            dir = (dir + 2) % 4;
        vis[x][y] = 1;
        x = x + dx[dir], y = y + dy[dir];
        if (x > n || y > m || x < 1 || y < 1)
        {
            ansx = x;
            ansy = y;
            return;
        }
    }
}

void solve2()
{
    int x = n, y = m, dir = 1;
    while (1)
    {
        if (a[x][y] == 1)
            dir = 3 - dir;
        if (a[x][y] == 2)
            dir = (dir + 2) % 4;
        if (vis[x][y] && !a[x][y])
        {
            e[++cnt].x = x;
            e[cnt].y = y;
            vis[x][y] = 0;
        }
        x += dx[dir], y += dy[dir];
        if (x > n || y > m || x < 1 || y < 1)
            return;
    }
}

int main()
{
    while (scanf("%d", &n) != EOF)
    {
        scanf("%d%d%d", &m, &A, &B);
        cnt = 0;
        ansx = 0;
        ansy = 0;
        //memset(vis, 0, sizeof(vis));
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                vis[i][j] = a[i][j] = 0;
        //memset(a, 0, sizeof(a));
        for (int i = 1; i <= A; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            a[x][y] = 1;
        }
        for (int i = 1; i <= B; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            a[x][y] = 2;
        }
        solve1();
        if (ansx == n && ansy == m + 1)
        {
            printf("0
");
            continue;
        }
        solve2();
        if (cnt == 0)
        {
            printf("-1
");
            continue;
        }
        sort(e + 1, e + 1 + cnt, cmp);
        printf("%d %d %d
", cnt, e[1].x, e[1].y);
    }

    return 0;
}

std:

#include<cstdio>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
#define rep(i,n) for (int i=0;i<n;++i)
#define pb push_back
#define mk make_pair
#define X first
#define Y second
#define tree int t,int l,int r
#define left t*2,l,mid
#define right t*2+1,mid+1,r
#define M int mid=l+r>>1
const int N=1000005;
typedef pair<int,int> pr;
typedef vector<pair<int,pr> > seq;
set<pr> a[N],b[N]; seq f1,g1,f2,g2; int Case,n,m,R,C,x,y,ll,rr,c[N]; long long ans;
int get(int x){int res=0; for (;x;x-=x&-x) res+=c[x]; return res;}
void add(int x,int v){for (;x<=C;x+=x&-x) c[x]+=v;}
void ins(int side){scanf("%d%d",&x,&y),a[x].insert(mk(y,side)),b[y].insert(mk(x,side));}
bool track(int x,int y,int d,seq &f,seq &g)
{
    f.clear(),g.clear(); set<pr> :: iterator it;
    for (;;){
        if (d&1){
            if (d==1){
                it=b[y].upper_bound(mk(x,1)); f.pb(mk(x+1,mk(y,1)));
                if (it==b[y].end()) return f.pb(mk(R+1,mk(y,-1))),0;
                f.pb(mk(it->X,mk(y,-1))),x=it->X,d=it->Y?2:0;
            }else{
                it=b[y].lower_bound(mk(x,0)); f.pb(mk(x,mk(y,-1)));
                if (it==b[y].begin()) return f.pb(mk(1,mk(y,1))),0; --it;
                f.pb(mk(it->X+1,mk(y,1))),x=it->X,d=it->Y?0:2;
            }
        }else{
            if (d==0){
                it=a[x].upper_bound(mk(y,1));
                if (it==a[x].end()) return g.pb(mk(x,mk(y+1,C))),x==R;
                g.pb(mk(x,mk(y+1,it->X-1))),y=it->X,d=it->Y?3:1;
            }else{
                it=a[x].lower_bound(mk(y,0));
                if (it==a[x].begin()) return g.pb(mk(x,mk(1,y-1))),0; --it;
                g.pb(mk(x,mk(it->X+1,y-1))),y=it->X,d=it->Y?1:3;
            }
        }
    }
}
void work(seq &f,seq &g)
{
    sort(f.begin(),f.end()),sort(g.begin(),g.end());
    int m=f.size(),n=g.size(),j=0;
    rep(i,n){
        while (j<m && f[j].X<=g[i].X) add(f[j].Y.X,f[j].Y.Y),++j;
        ll=g[i].Y.X,rr=g[i].Y.Y; int res=get(rr)-get(ll-1); ans+=res;
        if (g[i].X<x && res){
            x=g[i].X,y=ll;
            for (int j=20;j>=0;--j)
                if (y+(1<<j)<=rr && !(get(y-1+(1<<j))-get(y-1))) y+=1<<j;
            }
        }
    while (j<m) add(f[j].Y.X,f[j].Y.Y),++j;
}
int main()
{
    freopen("safe.in", "r", stdin);
    freopen("safe.out", "w", stdout);
    
    while (scanf("%d%d%d%d",&R,&C,&n,&m)!=EOF){
        rep(i,R+1) a[i].clear(); rep(j,C+1) b[j].clear();
        rep(i,n+m) ins(i<n);
        if (track(1,0,0,f1,g1)){puts("0"); continue;} track(R,C+1,2,f2,g2);
        ans=0,x=R+1,work(f1,g2),work(f2,g1);
        if (ans) printf("%lld %d %d
",ans,x,y); else puts("-1");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zbtrs/p/7728477.html