zoukankan      html  css  js  c++  java
  • HIT第二周 周测补题

    A    ARK

    搜素加剪枝。

    写完了题发现T了,折腾半天,发现题意理解错了。题意中的每班公交的起始时间i必须小于间隔时间j(因为是班车,在时间i之前公交还有停靠过,只是这些停靠不在12:00至12:59的范围内)。而我理解成了起始时间i之前公交没有停靠过(企业级李姐),导致多算了公交班次的类型,导致了TLE。。。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 2000
    using namespace std;
    int ans,n,tot,cnt[65];
    struct node
    {
        int a,b,times;
    }e[2000];
    bool cmp(node x,node y){return x.times>y.times;}
    int jud(int x,int y)
    {
        int re=0;
        while (x<60)
        {
            if (!cnt[x]) return 0;
            x+=y;re++;
        }
        return re;
    }
    void dfs(int k,int x,int num)
    {
        if (x>=ans) return;
        if (num==n)
        {
            if (x<ans) ans=x;
            return;
        }
        int i,j;
        for (i=k;i<=tot;i++)
        {
            if (x+(n-num)/e[i].times>=ans) return;
            if (!jud(e[i].a,e[i].b)) continue;
            for (j=0;j<e[i].times;j++) cnt[e[i].a+e[i].b*j]--;
            dfs(i,x+1,num+e[i].times);
            for (j=0;j<e[i].times;j++) cnt[e[i].a+e[i].b*j]++;
        }
    }
    int main()
    {
        int i,j,k,x,re;
        while (scanf("%d",&n)!=EOF)
        {
            memset(cnt,0,sizeof(cnt));
            tot=0;
            for (i=1;i<=n;i++) 
            {
                scanf("%d",&x);
                cnt[x]++;
            }
            for (i=0;i<30;i++)
            for (j=i+1;i+j<60;j++)
            {
                re=jud(i,j);
                if (re>=2)
                {
                    e[++tot].a=i;
                    e[tot].b=j;
                    e[tot].times=re;
                }
            }
            sort(e+1,e+tot+1,cmp);
            ans=17;
            dfs(1,0,0);
            printf("%d
    ",ans);
        }
        return 0; 
    }

    E    Everspace

    跑一遍马拉车,枚举第一部分回文串中心i,再枚举第三部分的回文串中心j。如果以这两点为中心的最长回文串都可以覆盖两部分之间的第二部分,即j-i<=min(p[i],p[j]),则符合题意。其中j-i为第二部分的长度的两倍(因为马拉车插入了新数,所以是两倍),所以答案就是(j-i)/2*3。统计其中的最大值即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 200005
    #define inf 1000000005;
    using namespace std;
    int p[maxn],len,a[maxn],s[maxn];
    void manacher()
    {
        int mx=0,id,i;
        for (i=1;i<len;i++)
        {
            if (mx>i) p[i]=min(p[2*id-i],mx-i);
            else p[i]=1;
            while (s[i+p[i]]==s[i-p[i]]) p[i]++;
            if (i+p[i]>mx)
            {
                id=i;
                mx=i+p[i];
            }
        }
    }
    int main()
    {
        int t,i,j,k,x,y,ans;
        scanf("%d",&t);
        for (k=1;k<=t;k++)
        {
            scanf("%d",&len);
            for (i=0;i<len;i++) scanf("%d",&a[i]);
            memset(p,0,sizeof(p));
            for (i=0;i<len;i++) 
            {
                s[i*2+1]=a[i];
                s[i*2+2]=inf;
            }
            len=len*2;
            s[0]=inf-1;
            s[++len]=inf-2;
            manacher();
            ans=0;
            for (i=0;i<len;i+=2)//对称,回文串中心为'#',所以+=2 
            for (j=i+p[i]-1;j>i;j-=2)
            {
                if (j-i<=ans) break;
                if (j-p[j]<=i) ans=j-i;
            }
            printf("Case #%d: %d
    ",k,ans/2*3);
        }
        return 0;
    }

    F    Fallout

    给一个地图,地图中1表示障碍物,现在给定机器人的初始位置与初始朝向,机器人每次操作可以向面向的方向走1或2或3个单位,也可以向右或者向左转90度,求机器人到达目标位置所需的最小操作数。

    求最短路,明显的bfs。(所以为什么我没写出来。。)需要注意机器人占地4个单位格子,需要判断这四个格子都没有障碍物才能走。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 52
    using namespace std;
    int n,m,sx,sy,tx,ty;
    int mp[maxn][maxn],vis[maxn][maxn][4],dis[maxn][maxn][4];
    int dr[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//北0东1南2西3 
    struct node
    {
        int x,y,d;
    }q[10010];
    int bfs(int x,int y,int dir)
    {
        int l=0,r=0,dd,xx,yy,i;
        q[++r].x=x;
        q[r].y=y;
        q[r].d=dir;
        vis[x][y][dir]=1;
        dis[x][y][dir]=0;
        while (l<r)
        {
            x=q[++l].x;
            y=q[l].y;
            dir=q[l].d;
            if (tx==x && ty==y) return dis[x][y][dir];
            for (i=1;i<=3;i++)
            {
                xx=x+i*dr[dir][0];
                yy=y+i*dr[dir][1];
                if (xx<1 || xx>=n || yy<1 || yy>=m) break; 
                if (mp[xx][yy] || mp[xx+1][yy] || mp[xx][yy+1] || mp[xx+1][yy+1]) break;
                if (!vis[xx][yy][dir])
                {
                    vis[xx][yy][dir]=1;
                    q[++r].x=xx;
                    q[r].y=yy;
                    q[r].d=dir;
                    dis[xx][yy][dir]=dis[x][y][dir]+1;
                }
            }
            dd=(dir-1+4)%4;//左转 
            if (!vis[x][y][dd])
            {
                vis[x][y][dd]=1;
                q[++r].x=x;
                q[r].y=y;
                q[r].d=dd;
                dis[x][y][dd]=dis[x][y][dir]+1;
            }
            dd=(dir+1)%4;//右转 
            if (!vis[x][y][dd])
            {
                vis[x][y][dd]=1;
                q[++r].x=x;
                q[r].y=y;
                q[r].d=dd;
                dis[x][y][dd]=dis[x][y][dir]+1;
            }
        }
        return -1;
    }
    int main()
    {
        int i,j,d;
        char s[10];
        while (scanf("%d%d",&n,&m)!=EOF && (n!=0 || m!=0))
        {
            memset(vis,0,sizeof(vis));
            memset(dis,0,sizeof(dis));
            for (i=1;i<=n;i++)
            for (j=1;j<=m;j++) scanf("%d",&mp[i][j]);
            scanf("%d%d%d%d%s",&sx,&sy,&tx,&ty,s);
            if (s[0]=='n') d=0;
            else if (s[0]=='e') d=1;
            else if (s[0]=='s') d=2;
            else d=3;
            printf("%d
    ",bfs(sx,sy,d));
        }
        return 0;
    }

    H    Halo

    异或知识+tries树

    计算从根节点到每个点的异或距离,再从中找出两个异或后值最大的即可。

    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define maxn 100100
    using namespace std;
    typedef long long ll;
    struct node
    {
        int to,nxt,w;
    }e[maxn*2];
    int num,last[maxn],ch[maxn*32][2],cnt;
    ll f[maxn],note[maxn*32];
    void add(int x,int y,int z)
    {
        e[++num].to=y;
        e[num].nxt=last[x];
        last[x]=num;
        e[num].w=z;
    }
    
    void build(ll now)
    {
        int i,u=0,x;
        for (i=31;i>=0;i--)
        {
            x=(now>>i)&1;
            if (!ch[u][x]) ch[u][x]=++cnt;
            u=ch[u][x];
        }
        note[u]=now;
    }
    ll find(ll now)
    {
        int i,u=0,x;
        for (i=31;i>=0;i--)
        {
            x=(now>>i)&1;
            if (ch[u][x^1]) u=ch[u][x^1];
            else u=ch[u][x];
        }
        return note[u];
    }
    void dfs(int fa,int x)
    {
        for (int i=last[x];i!=-1;i=e[i].nxt)
        {
            if (e[i].to==fa) continue;
            f[e[i].to]=f[x]^e[i].w;
            dfs(x,e[i].to);
        }
    }
    int main()
    {
        int n,x,y,z,i;
        ll tmp,ans;
        while (scanf("%d",&n)!=EOF)
        {
            memset(last,-1,sizeof(last));
            memset(f,0,sizeof(f));
            memset(ch,0,sizeof(ch));
            memset(note,0,sizeof(note));
            num=0;cnt=0;ans=0;
            for (i=1;i<n;i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                add(x,y,z);
                add(y,x,z);
            }
            build(0);
            dfs(0,0);
            for (i=0;i<n;i++) build(f[i]);
            for (i=0;i<n;i++)
            {
                tmp=find(f[i])^f[i];
                if (tmp>ans) ans=tmp;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }

    I    Icey

    J    Just Cause

    K    Kerbal Space Program

  • 相关阅读:
    CSS的一些单位,如rem、px、em、vw、vh、vm
    js判断浏览器的类型
    VUE项目引入jquery
    安装搭配VUE使用的UI框架ElementUI
    VUE环境搭建,项目配置(Windows下)
    纯CSS写的各种小三角和小箭头
    改变input的placeholder字体颜色
    LR
    使用WebKit.net加载HTML编辑器
    c# 打开指定的网址
  • 原文地址:https://www.cnblogs.com/lsykk/p/13460313.html
Copyright © 2011-2022 走看看