蚂蚁

原来是一道很简单的枚举题,然后我把它加难了一点点。

题意是,给你N个点,它们会向四周一个固定的方向移动,它们的速度都是相同的,当相撞的时候所有正好运动到这个地方的点都会消失。问最后还会剩下多少个点

原本N<=50并且都会在4000到-4000的范围内,然后我机智的改成了N<=8000并且没有范围限制.

于是我们可以在坐标系内搞定

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define N 5005
#define inf 1005
using namespace std;
int f[N],an[N],ans,n,tot;
int d[N][2];
//int a[N][N];
struct wakaka
{
       int key,x,y;
       }e[N*5];
bool check2(int x,int y)
{
     int x1=d[x][0],y1=d[x][1],f1=f[x],x2=d[y][0],y2=d[y][1],f2=f[y];
     if (d[x][1]<d[y][1]) {swap(x1,x2);swap(y1,y2);swap(f1,f2);}
//     printf("%d %d %d %d %d %d           %d %d\n",x1,y1,f1,x2,y2,f2,x,y);
     if (x1>x2)
     {
               if (f1==2&&f2==4) return true;
               if (f1==3&&f2==1) return true;
               return false;
               }
     if (x1<x2)
     {
               if (f1==4&&f2==1) return true;
               if (f1==2&&f2==3) return true;
               return false;
               }
     }

int calc(int x,int y)
{
     if (x==y) return inf;
     if (f[x]==f[y]) return inf;
     if (d[x][0]==d[y][0])
     {
                          if (d[x][1]>d[y][1]&&f[x]==2&&f[y]==1)
                          {
                                                                return (d[x][1]-d[y][1]);
                                                                }
                          if (d[x][1]<d[y][1]&&f[x]==1&&f[y]==2)
                          {
                                                                return (d[y][1]-d[x][1]);
                                                                }
                          return inf;
                          }
     if (d[x][1]==d[y][1])
     {
                          if (d[x][0]>d[y][0]&&f[x]==3&&f[y]==4)
                          {
                                                                return (d[x][0]-d[y][0]);
                                                                }
                          if (d[x][0]<d[y][0]&&f[x]==4&&f[y]==3)
                          {
                                                                return (d[y][0]-d[x][0]);
                                                                }
                          return inf;
                          }
     if (abs(d[x][1]-d[y][1])==abs(d[x][0]-d[y][0])&&check2(x,y)) return abs(d[x][1]-d[y][1])*2;
     return inf;
     }

void check(int x,int y)
{
//     a[y][x]=a[x][y]=calc(x,y);
     int k=calc(x,y);
     if (k!=inf)
     {
                      e[++tot].key=k;
                      e[tot].x=x;e[tot].y=y;
                      }
     }
     
bool com(wakaka a,wakaka b)
{
     if (a.key<b.key) return 1; else return 0;
     }

int main()
{
    freopen("ant.in","r",stdin);
    freopen("ant.out","w",stdout);
    scanf("%d",&n);getchar();
    for (int i=1;i<=n;i++)
    {
        int ch=getchar();
        if (ch=='N') f[i]=1;
        if (ch=='S') f[i]=2;
        if (ch=='W') f[i]=3;
        if (ch=='E') f[i]=4;
//        cout<<f[i]<<' ';
        }
//    cout<<endl;
    for (int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d %d\n",&x,&y);
        d[i][0]=x;d[i][1]=y;
        }
    for (int i=1;i<=n;i++)
        for (int j=i;j<=n;j++)
            check(i,j);
    sort(e+1,e+tot+1,com);
    int anss=0;memset(an,1,sizeof(an));
    for (int i=1;i<=tot;i++)
    {
        int t=e[i].key,x=e[i].x,y=e[i].y;
        if (!an[x]||!an[y]) continue;
//        cout<<x<<' '<<y<<endl;
        anss+=2;an[x]=0;an[y]=0;
        for (int j=1;j<=n;j++)
        {
            if (calc(x,j)==t&&an[j])
            {
                                  an[j]=0;
                                  anss++;
                                  }
            if (calc(y,j)==t&&an[j])
            {
                                   an[j]=0;
                                   anss++;
                                   }
            }
        }

    printf("%d\n",n-anss);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值