• 8-2测试总结


    T1,不多说,pascal自带的pos轻松过,枚举第一个删AC或CA,水过~~

    T2,meet in the middle,不过在用扩欧的时候要注意如果ex_gcd(a,b,x,y)中的a或b=0,直接退出。炸了85分~~

    T3,一个暴力,靠着没有正确性的暴力居然有50分,感人。

    总结:T2这种数学题对边界如0这种还是要好好思考一下的,比如说如果用费马小定理求逆元的话更加要注意了p=2的情况(YHYHYH3提醒)

    写一下T3的题。

    这道题我写了一个广搜,其实正解也是广搜,一般我们广搜都是对(x,y)的二元组惊醒搜索的,但是这道题我们发现一条蛇可以多次走一个点(不多于两次吧),所以我们要加入另一个状态(x,y,body),表示其蛇头在这个点时的姿态?因为len<=8(哦照片没拍出来),所以我们可以用压位来操作。

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <climits>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    int n, m, l, x, y, x2, y2;
    int cx[4] = {1, 0, -1, 0};
    int cy[4] = {0, 1, 0, -1};
    int head, tail, i, j, k, num, dk, ans;
    bool flag;
    struct Node
    {
        int x, y, z;
    } d[8000000];
    int b[29][29][24010], f[29][29][24010], snackx[10], snacky[10], F[2100][2100], T[10];
    bool abletogo[2100][2100];
    int main()
    {
        freopen("snake.in", "r", stdin);
        freopen("snake.out", "w", stdout);
        int t;
        scanf("%d", &t);
        while (t--)
        {
            scanf("%d%d%d", &n, &m, &l);
            if (l == 1)
            {
                for (int i = 1; i <= n; i++)
                    for (int j = 1; j <= m; j++)
                        abletogo[i][j] = 0, F[i][j] = -1;
                scanf("%d%d", &x, &y);
                abletogo[x][y] = 1;
                head = tail = 1;
                d[tail].x = x;
                d[tail].y = y;
                F[x][y] = 0;
                scanf("%d", &k);
                for (int i = 1; i <= k; i++)
                {
                    scanf("%d%d", &x, &y);
                    abletogo[x][y] = 1;
                }
                while (head <= tail)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        x2 = d[head].x + cx[i];
                        y2 = d[head].y + cy[i];
                        if (x2 < 1 || x2 > n || y2 < 1 || y2 > m || abletogo[x2][y2])
                            continue;
                        abletogo[x2][y2] = 1;
                        F[x2][y2] = F[d[head].x][d[head].y] + 1;
                        tail++;
                        d[tail].x = x2;
                        d[tail].y = y2;
                    }
                    head++;
                }
                printf("%d
    ", F[1][1]);
            }
            else
            {
                for (int i = 1; i <= l; i++)
                    scanf("%d%d", &snackx[i], &snacky[i]);
                num = 0;
                for (int i = 1; i < l; i++)
                {
                    for (int j = 0; j < 4; j++)
                        if (snackx[i] + cx[j] == snackx[i + 1] && snacky[i] + cy[j] == snacky[i + 1])
                        {
                            num = num * 4 + j;
                            break;
                        }
                }
                for (int i = 1; i <= n; i++)
                    for (int j = 1; j <= m; j++)
                        for (int dk = 0; dk <= 1 << 14; dk++)
                            b[i][j][dk] = 0, f[i][j][dk] = -1;
                b[snackx[1]][snacky[1]][num] = 1;
                f[snackx[1]][snacky[1]][num] = 0;
                head = tail = 1;
                d[tail].x = snackx[1];
                d[tail].y = snacky[1];
                d[tail].z = num;
                scanf("%d", &k);
                for (int i = 1; i <= k; i++)
                {
                    scanf("%d%d", &x, &y);
                    for (int j = 0; j <= 1 << 14; j++)
                        b[x][y][j] = 1;
                }
                while (head <= tail)
                {
                    num = d[head].z;
                    for (int i = l - 1; i; i--)
                    {
                        T[i] = num % 4;
                        num /= 4;
                    }
                    snackx[1] = d[head].x, snacky[1] = d[head].y;
                    for (int i = 1; i <= l - 1; i++)
                    {
                        snackx[i + 1] = snackx[i] + cx[T[i]];
                        snacky[i + 1] = snacky[i] + cy[T[i]];
                    }
                    for (int i = 0; i < 4; i++)
                    {
                        x2 = snackx[1] + cx[i];
                        y2 = snacky[1] + cy[i];
                        if (x2 < 1 || x2 > n || y2 < 1 || y2 > m)
                            continue;
                        flag = false;
                        for (int j = 1; j <= l - 1; j++)
                            if (x2 == snackx[j] && y2 == snacky[j])
                            {
                                flag = true;
                                break;
                            }
                        if (flag)
                            continue;
                        num = (i + 2) % 4;
                        for (int j = 1; j < l - 1; j++)
                            num = num * 4 + T[j];
                        if (b[x2][y2][num])
                            continue;
                        b[x2][y2][num] = 1;
                        f[x2][y2][num] = f[d[head].x][d[head].y][d[head].z] + 1;
                        tail++;
                        d[tail].x = x2;
                        d[tail].y = y2;
                        d[tail].z = num;
                    }
                    head++;
                }
                ans = INT_MAX;
                for (int i = 0; i <= 1 << 14; i++)
                    if (f[1][1][i] != -1)
                        ans = min(ans, f[1][1][i]);
                if (ans == INT_MAX)
                    printf("-1
    ");
                else
                    printf("%d
    ", ans);
            }
        }
    }
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define ll long long
    int n,m,z,L,body,step=-1;
    int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0},Pow[10];
    int change[20000][4];
    bool f[20000],flag[21][21][20000],duang[2011][2011],bo[100][100];
    struct snake{
        int x[8],y[8],z,body;
    }s,news;
    queue<snake> Q;
    int calc_body(snake s)
    {
        int id=0;
        for(int i=1;i<L;i++)
        {
            int cx=s.x[i]-s.x[i-1],cy=s.y[i]-s.y[i-1];
            int j=0;
            for(j=0;j<4;j++)
            {
                if(dx[j]==cx&&dy[j]==cy) break;
            }
            id=id*4+j;
        }
        return id;
    }
    void solve()
    {
        while(!Q.empty()) Q.pop();
        s.body=calc_body(s);
        Q.push(s);
        flag[s.x[0]][s.y[0]][s.body]=1;
        while(!Q.empty()&&step==-1)
        {
            s=Q.front();Q.pop();
            for(int i=0;i<4;i++)
            {
                int x=s.x[0]+dx[i],y=s.y[0]+dy[i],z=s.z+1,body=change[s.body][i];
                if(x<=0||x>n||y<=0||y>m||flag[x][y][body]||duang[x][y]||(!f[body])) continue;
                if(x==1&&y==1)
                {
                    step=z;
                    break;
                }
                news.z=z;news.x[0]=x,news.y[0]=y;news.body=body;
                Q.push(news);
                flag[x][y][body]=1;
            }
        }
        cout<<step<<endl;
    }
    void bfs()
    {
        while(!Q.empty()) Q.pop();
        Q.push(s);
        duang[s.x[0]][s.y[0]]=1;
        while(!Q.empty())
        {
            s=Q.front();
            Q.pop();
            for(int i=0;i<4;i++)
            {
                int x=s.x[0]+dx[i],y=s.y[0]+dy[i],z=s.z+1;
                if(x<=0||x>n||y<=0||y>m||duang[x][y])continue;
                if(x==1&&y==1) { step=z;break;}
                news.x[0]=x,news.y[0]=y,news.z=z;
                Q.push(news);
                duang[x][y]=1; 
            }
        }
        cout<<step<<endl;
    }
    void prepare()
    {
        Pow[0]=1;
        for(int i=1;i<10;i++) Pow[i]=Pow[i-1]*4;
        
        for(int i=0;i<Pow[L-1];i++)//除了头以外每一位都由原先的高一位来代替,最高位就是当前的方向啦 
            for(int j=0;j<4;j++)
            {
                change[i][j]=i/4+(j+2)%4*Pow[L-2];
             }
        //判断一个蛇是否会碰到自己 
        memset(f,true,sizeof(f));
        for(int i=0;i<Pow[L-1];i++)
        {
            memset(bo,0,sizeof(bo));
            int x=10,y=10;//随便从中间找一个点向4周扩展 
            bo[x][y]=1;
            for(int j=L-1;j>=1;j--)
            {
                int t=i%Pow[j]/Pow[j-1];
                x+=dx[t];y+=dy[t];
                if(bo[x][y])
                {
                    f[i]=false;
                    break;
                }
                bo[x][y]=1;
            }
        }      
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            step=-1;
            memset(flag,0,sizeof(flag));
            memset(duang,0,sizeof(duang));
            scanf("%d %d %d",&n,&m,&L);
            prepare();
            for(int i=0;i<L;i++)
                scanf("%d %d",&s.x[i],&s.y[i]);
            s.z=0;
            int k;
            scanf("%d",&k);
            for(int i=1;i<=k;i++)
            {
                int a,b;
                scanf("%d %d",&a,&b);
                duang[a][b]=true;
            }
            if(s.x[0]==1&&s.y[0]==1)
            {
                cout<<0<<endl;
                continue;
            }
            if(L==1) bfs();
            else solve();
        }
        return 0;
     } 
  • 相关阅读:
    Qt 为何toggled无法触发setvisible(转)
    C++中const用法总结(转)
    C++输入输出流格式控制(转)
    ios-->iTunes同步应用失败
    apk签名
    常见缩写
    转:web_custom_request应用示例
    转:web_custom_request 函数
    转:web_submit_data函数
    转:web_custom_request 和 web_submit_data的差别
  • 原文地址:https://www.cnblogs.com/dancer16/p/7275986.html
Copyright © 2020-2023  润新知