USACO 2016 December Contest总结

比赛链接

T1 Moocast

题目链接

题目大意:确定一个最小的通信距离使得一个平面上给定一些点直接或间接联通。

思路:二分。五分钟做出来了。。。

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#include<set>
#include<cctype>
#define pa pair<int,int>
#define INF 0x3f3f3f3f
#define inf 0x3f
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define pb push_back

using namespace std;

inline ll read()
{
    long long f=1,sum=0;
    char c=getchar();
    while (!isdigit(c)) {if (c=='-') f=-1;c=getchar();}
    while (isdigit(c)) {sum=sum*10+c-'0';c=getchar();}
    return sum*f;
}
const int MAXN=1010;
struct node
{
    int x,y;
};
node a[MAXN];
int fa[MAXN],n;
int find(int x)
{
    if (fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}
bool check(int mid)
{
    for (int i=1;i<=n;i++)
        fa[i]=i;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        {
            ll dis=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
            if (dis<=(ll)mid)
            {
                int f1=find(i),f2=find(j);
                if (f1!=f2) fa[f1]=f2;
            }
        }
    }
    int anc=find(1);
    for (int i=2;i<=n;i++)
        if (find(i)!=anc)
            return 0;
    return 1;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
        scanf("%d%d",&a[i].x,&a[i].y);
    int l=0,r=1e9,mid,ans;
    while (l<=r)
    {
        mid=(l+r)>>1;
        if (check(mid))
            ans=mid,r=mid-1;
        else
            l=mid+1;
    }
    cout<<ans;
    return 0;
}

T2 Cow Checklist

题目链接

题目大意:平面上有两组点,分别是N个,M个。
你要从第一组的第一个开始访问所有点,再回到第一组的最后一个。要求同一组内编号小的点必须在编号大的点之前访问。定义耗损为两个点之间的距离的平方。构造一个访问序列使得耗损最小,求最小耗损。

思路:DP
- f [ i ] [ j ] [ 0 / 1 ] 表示第一个序列的前i个点,第二个序列的前j个点被访问过,你现在在第一组点还是在第二组点。
- 转移:

{ f [ i ] [ j ] [ 0 ] = m i n ( f [ i 1 ] [ j ] [ 1 ] + d i s , f [ i 1 ] [ j ] [ 0 ] + d i s ) f [ i ] [ j ] [ 1 ] = m i n ( f [ i ] [ j 1 ] [ 0 ] + d i s , f [ i ] [ j 1 ] [ 1 ] + d i s )

- 其中dis为两点之间距离。

代码忘记上传了。。。

T3 Lasers and Mirrors

题目链接

题目大意:二维平面内有 N ( N 10 6 ) 个点,有一个激光发射器和一个接收器。现在要在点上安装镜子(光线只能垂直于坐标轴),问最少安装几个镜子才能让接收器收到激光 ,或不可能。

思路:先离散化,然后BFS。
- 考察了对iterator的使用。。。

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<map>
#include<queue>
#include<vector>
#include<stack>
#include<set>
#include<cctype>
#define pa pair<int,int>
#define INF 0x3f3f3f3f
#define inf 0x3f
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define pb push_back

using namespace std;

inline ll read()
{
    long long f=1,sum=0;
    char c=getchar();
    while (!isdigit(c)) {if (c=='-') f=-1;c=getchar();}
    while (isdigit(c)) {sum=sum*10+c-'0';c=getchar();}
    return sum*f;
}
const int MAXN=100010;
struct node
{
    int x,y;
};
node a[MAXN];
vector <int> vx,vy;
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
vector <int> x[MAXN],y[MAXN];
bool visit[MAXN][5];
queue <pair<pa,pa> > q;
map <pa,int> id; 
#define ps(x,y,a,b) q.push(make_pair(make_pair(x,y),make_pair(a,b)))
int main()
{
    int n;
    node st,ed;
    scanf("%d%d%d%d%d",&n,&st.x,&st.y,&ed.x,&ed.y);
    vx.push_back(st.x),vy.push_back(st.y);
    vx.push_back(ed.x),vy.push_back(ed.y);
    for (int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y);
        vx.push_back(a[i].x),vy.push_back(a[i].y);
    }
    sort(vx.begin(),vx.end()),sort(vy.begin(),vy.end());
    vx.resize(unique(vx.begin(),vx.end())-vx.begin());
    vy.resize(unique(vy.begin(),vy.end())-vy.begin());
    for (int i=1;i<=n;i++)
    {
        a[i].x=lower_bound(vx.begin(),vx.end(),a[i].x)-vx.begin()+1;
        a[i].y=lower_bound(vy.begin(),vy.end(),a[i].y)-vy.begin()+1;
        id[make_pair(a[i].x,a[i].y)]=i;
        x[a[i].x].push_back(a[i].y);
        y[a[i].y].push_back(a[i].x);
    }
    st.x=lower_bound(vx.begin(),vx.end(),st.x)-vx.begin()+1;
    st.y=lower_bound(vy.begin(),vy.end(),st.y)-vy.begin()+1;
    ed.x=lower_bound(vx.begin(),vx.end(),ed.x)-vx.begin()+1;
    ed.y=lower_bound(vy.begin(),vy.end(),ed.y)-vy.begin()+1;
    x[st.x].push_back(st.y);
    y[st.y].push_back(st.x);
    x[ed.x].push_back(ed.y);
    y[ed.y].push_back(ed.x);
    for (int i=1;i<MAXN;i++)
        sort(x[i].begin(),x[i].end()),sort(y[i].begin(),y[i].end());
    int posx,posy;
    vector <int>::iterator it;
    it=upper_bound(x[st.x].begin(),x[st.x].end(),st.y);
    if (it!=x[st.x].end())
    {
        posx=st.x,posy=*it;
        ps(posx,posy,1,0);
    }
    it=lower_bound(x[st.x].begin(),x[st.x].end(),st.y);
    if (it!=x[st.x].begin())
    {
        it--;
        posx=st.x,posy=*it;
        ps(posx,posy,3,0);
    }
    it=upper_bound(y[st.y].begin(),y[st.y].end(),st.x);
    if (it!=y[st.y].end())
    {
        posx=*it,posy=st.y;
        ps(posx,posy,2,0);
    }
    it=lower_bound(y[st.y].begin(),y[st.y].end(),st.x);
    if (it!=y[st.y].begin())
    {
        it--;
        posx=*it,posy=st.y;
        ps(posx,posy,4,0);
    }
    while (!q.empty())
    {
        pair <pa,pa> now=q.front();
        q.pop();
        if (now.fi.fi==ed.x && now.fi.se==ed.y)
        {
            cout<<now.se.se;
            return 0;
        }
        int step=now.se.se;
        visit[id[make_pair(now.fi.fi,now.fi.se)]][now.se.fi]=1;
        int nx=now.fi.fi,ny=now.fi.se;
        if (now.se.fi==1)
        {
            it=upper_bound(x[nx].begin(),x[nx].end(),ny);
            if (it!=x[nx].end())
            {
                posx=nx,posy=*it;
                if (!visit[id[make_pair(posx,posy)]][1])
                    ps(posx,posy,1,step);
            }
            it=upper_bound(y[ny].begin(),y[ny].end(),nx);
            if (it!=y[ny].end())
            {
                posx=*it,posy=ny;
                if (!visit[id[make_pair(posx,posy)]][2])
                    ps(posx,posy,2,step+1);
            }
            it=lower_bound(y[ny].begin(),y[ny].end(),nx);
            if (it!=y[ny].begin())
            {
                it--;
                posx=*it,posy=ny;
                if (!visit[id[make_pair(posx,posy)]][4])
                    ps(posx,posy,4,step+1);
            }
        }
        else if (now.se.fi==2)
        {
            it=upper_bound(y[ny].begin(),y[ny].end(),nx);
            if (it!=y[ny].end())
            {
                posx=*it,posy=ny;
                if (!visit[id[make_pair(posx,posy)]][2])
                    ps(posx,posy,2,step);
            }
            it=upper_bound(x[nx].begin(),x[nx].end(),ny);
            if (it!=x[nx].end())
            {
                posx=nx,posy=*it;
                if (!visit[id[make_pair(posx,posy)]][1])
                    ps(posx,posy,1,step+1);
            }
            it=lower_bound(x[nx].begin(),x[nx].end(),ny);
            if (it!=x[nx].begin())
            {
                it--;
                posx=nx,posy=*it;
                if (!visit[id[make_pair(posx,posy)]][1])
                    ps(posx,posy,3,step+1);
            }
        }
        else if (now.se.fi==3)
        {
            it=lower_bound(x[nx].begin(),x[nx].end(),ny);
            if (it!=x[nx].begin())
            {
                it--;
                posx=nx,posy=*it;
                if (!visit[id[make_pair(posx,posy)]][1])
                    ps(posx,posy,3,step);
            }
            it=upper_bound(y[ny].begin(),y[ny].end(),nx);
            if (it!=y[ny].end())
            {
                posx=*it,posy=ny;
                if (!visit[id[make_pair(posx,posy)]][2])
                    ps(posx,posy,2,step+1);
            }
            it=lower_bound(y[ny].begin(),y[ny].end(),nx);
            if (it!=y[ny].begin())
            {
                it--;
                posx=*it,posy=ny;
                if (!visit[id[make_pair(posx,posy)]][4])
                    ps(posx,posy,4,step+1);
            }               
        }
        else
        {
            it=lower_bound(y[ny].begin(),y[ny].end(),nx);
            if (it!=y[ny].begin())
            {
                it--;
                posx=*it,posy=ny;
                if (!visit[id[make_pair(posx,posy)]][4])
                    ps(posx,posy,4,step);
            }
            it=upper_bound(x[nx].begin(),x[nx].end(),ny);
            if (it!=x[nx].end())
            {
                posx=nx,posy=*it;
                if (!visit[id[make_pair(posx,posy)]][1])
                    ps(posx,posy,1,step+1);
            }
            it=lower_bound(x[nx].begin(),x[nx].end(),ny);
            if (it!=x[nx].begin())
            {
                it--;
                posx=nx,posy=*it;
                if (!visit[id[make_pair(posx,posy)]][1])
                    ps(posx,posy,3,step+1);
            }
        }
    }
    cout<<-1<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/szh_0808/article/details/80496683