日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[ZJOI2014] 璀璨光华(bfs建图 + dfs搜索)

發(fā)布時間:2023/12/3 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [ZJOI2014] 璀璨光华(bfs建图 + dfs搜索) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

problem

luogu-P3342

solution

你感覺這道題沒考什么,又感覺考了什么

通過樣例以及題面,我們并未獲取到『立方體每個小方塊的編號是按一定規(guī)則命名』的信息。

也就是說,我們需要通過輸入的每個小方塊相鄰的編號的信息來建出這個立方體的坐標系。

我的做法較暴力但不用思考太多,簡單易上手。你值得擁有

  • 首先,我們先隨便找一個三度點(只有三個水晶和該水晶有公共面),欽定為 (1,1,1)(1,1,1)(1,1,1)

    然后以這個點 bfs\text{bfs}bfs 搜,得到每個點的距離,我們記為 dis0dis_0dis0?

  • 其次,我們再隨便找一個與上一個點距離恰好為 2n?22n-22n?2 的點,即 dis0(i)=2n?2dis_0(i)=2n-2dis0?(i)=2n?2,欽定為 (n,n,1)(n,n,1)(n,n,1)

    然后以這個點 bfs\text{bfs}bfs 搜,得到每個點的距離,我們記為 dis1dis_1dis1?

  • 接著,我們?nèi)噪S便找一個與上兩個點距離恰都為 n?1n-1n?1 的點,即 dis0(i)=dis1(i)=n?1dis_0(i)=dis_1(i)=n-1dis0?(i)=dis1?(i)=n?1,欽定為 (n,1,1)(n,1,1)(n,1,1)

    然后以這個點 bfs\text{bfs}bfs 搜,得到每個點的距離,我們記為 dis2dis_2dis2?

這里的距離指的是曼哈頓距離 x,y,zx,y,zx,y,z 三維坐標差的絕對值之和。

考慮小方塊 iii 的距離信息點對 (dis1(i)?dis0(i),dis2(i)?dis0(i))\Big(dis_1(i)-dis_0(i),dis_2(i)-dis_0(i)\Big)(dis1?(i)?dis0?(i),dis2?(i)?dis0?(i))

observation1:\text{observation1}:observation1: 該點對與 iii 的真正的 zzz 坐標無關(guān)。

observation2:\text{observation2}:observation2: 該點對與小方塊的真正 (x,y)(x,y)(x,y) 坐標存在一一對應關(guān)系。這只能自己臆想了

dis0(i)=(x,y,z)?(1,1,1)dis_0(i)=(x,y,z)\leftrightarrow (1,1,1)dis0?(i)=(x,y,z)?(1,1,1),所以我們可以選擇通過 dis0(i)dis_0(i)dis0?(i) 與已經(jīng)求出的 x,yx,yx,y 來推出小方塊的 zzz 坐標。

最后只用 dfs\text{dfs}dfs 暴搜枚舉每個特殊發(fā)光小水晶擴散的方向,O(6n)O(6^n)O(6n)

然后 check\text{check}check 沿著該方向枚舉一路上的水晶,用 visvisvis 標記是否已經(jīng)訪問過了,非第一次訪問不計入發(fā)光貢獻。

最后清空 vis\text{vis}vis 數(shù)組,也是按照方向清空。不然就是 O(a3)O(a^3)O(a3) 的復雜度了。

時間復雜度 O(6na)O(6^na)O(6na)

code

#include <bits/stdc++.h> using namespace std; #define maxn 400000 #define MAX 150 struct node { int x, y, z; }pos[MAX << 2][MAX << 2]; vector < int > G[maxn]; vector < node > NB; int g[maxn], dir[maxn]; int dis[3][maxn]; int vis[MAX][MAX][MAX], val[MAX][MAX][MAX]; int Min = 1e9, Max = -1e9, n, m; queue < int > q;void bfs( int s, int *dis ) {dis[s] = 0; q.push( s );while( ! q.empty() ) {int u = q.front(); q.pop();for( int v : G[u] ) if( dis[v] > dis[u] + 1 ) dis[v] = dis[u] + 1, q.push( v );} }void calc() {int sum = 0;for( int k = 0;k < NB.size();k ++ ) {int x = NB[k].x, y = NB[k].y, z = NB[k].z;switch( dir[k] ) {case 0 : {for( int i = 1;i <= x;i ++ )if( ! vis[i][y][z] )vis[i][y][z] = 1, sum += val[i][y][z];break;}case 1 : {for( int i = x;i <= n;i ++ )if( ! vis[i][y][z] )vis[i][y][z] = 1, sum += val[i][y][z];break;}case 2 : {for( int i = 1;i <= y;i ++ )if( ! vis[x][i][z] )vis[x][i][z] = 1, sum += val[x][i][z];break;}case 3 : {for( int i = y;i <= n;i ++ )if( ! vis[x][i][z] )vis[x][i][z] = 1, sum += val[x][i][z];break;}case 4 : {for( int i = 1;i <= z;i ++ )if( ! vis[x][y][i] )vis[x][y][i] = 1, sum += val[x][y][i];break;}case 5 : {for( int i = z;i <= n;i ++ )if( ! vis[x][y][i] )vis[x][y][i] = 1, sum += val[x][y][i];break;}}}Min = min( Min, sum ), Max = max( Max, sum );for( int k = 0;k < NB.size();k ++ ) {int x = NB[k].x, y = NB[k].y, z = NB[k].z;switch( dir[k] ) {case 0 : for( int i = 1;i <= x;i ++ ) vis[i][y][z] = 0; break;case 1 : for( int i = x;i <= n;i ++ ) vis[i][y][z] = 0; break;case 2 : for( int i = 1;i <= y;i ++ ) vis[x][i][z] = 0; break;case 3 : for( int i = y;i <= n;i ++ ) vis[x][i][z] = 0; break;case 4 : for( int i = 1;i <= z;i ++ ) vis[x][y][i] = 0; break;case 5 : for( int i = z;i <= n;i ++ ) vis[x][y][i] = 0; break;}} }void dfs( int x ) {if( x == NB.size() ) return calc(), void();for( int i = 0;i < 6;i ++ ) dir[x] = i, dfs( x + 1 ); }int CalcDis( int x, int y, int a, int b ) { return fabs( x - a ) + fabs( y - b ); }int main() {memset( dis, 0x3f, sizeof( dis ) );scanf( "%d", &n );m = n * n * n;for( int i = 1, id;i <= m;i ++ ) {scanf( "%d", &g[i] );do { scanf( "%d", &id ), G[i].push_back( id ); } while( getchar() != '\n' );}int p1, p2, p3;for( int i = 1;i <= m;i ++ ) if( G[i].size() == 3 ) p1 = i;val[1][1][1] = g[p1]; bfs( p1, dis[0] );for( int i = 1;i <= m;i ++ ) if( G[i].size() == 3 and dis[0][i] == (n - 1 << 1) ) p2 = i;val[n][n][1] = g[p2]; bfs( p2, dis[1] );for( int i = 1;i <= m;i ++ ) if( G[i].size() == 3 and dis[0][i] == n - 1 and dis[1][i] == n - 1 ) p3 = i;val[n][1][1] = g[p3]; bfs( p3, dis[2] );for( int i = 1;i <= n;i ++ )for( int j = 1;j <= n;j ++ ) {int d0 = CalcDis( 1, 1, i, j );int d1 = CalcDis( n, n, i, j );int d2 = CalcDis( n, 1, i, j );pos[MAX + d1 - d0][MAX + d2 - d0] = { i, j, 1 };}for( int i = 1;i <= m;i ++ ) {node p = pos[MAX + dis[1][i] - dis[0][i]][MAX + dis[2][i] - dis[0][i]];p.z = dis[0][i] - CalcDis( 1, 1, p.x, p.y ) + 1;val[p.x][p.y][p.z] = g[i];if( ! g[i] ) NB.push_back( p );}dfs( 0 );printf( "%d %d\n", Min, Max );return 0; }

總結(jié)

以上是生活随笔為你收集整理的[ZJOI2014] 璀璨光华(bfs建图 + dfs搜索)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。