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#include #include #include #include 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#include #include #include #include using namespace std;#define ll long longint 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 Q;int calc_body(snake s){ int id=0; for(int i=1;i 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< < 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< < =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