8-2测试总结

时间:2022-12-22 21:51:44

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的题。

8-2测试总结

8-2测试总结

这道题我写了一个广搜,其实正解也是广搜,一般我们广搜都是对(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\n", 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\n");
            else
                printf("%d\n", 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;
 }