【记忆化路线】
【记忆化路线】
Spirit of Cola.
https://ac.nowcoder.com/acm/contest/110312/J
注意写法积累!
(1)vector多维数组
//记最短路
vector dp(c[0] + 1, vector(c[1] + 1, vector<int>(c[2] + 1, -1)));
//记路线
vector last(c[0] + 1, vector(c[1] + 1, vector<array<int, 3>>(c[2] + 1, {-1, -1, -1})));
(2)lambda递归输出路线
auto pr=[&](auto self,int x,int y,int z)->void{
if(x==w[0] && y==w[1] && z==w[2]) return;
auto it=last[x][y][z];
//对自身的递归:self
self(self,it[0],it[1],it[2]);
//先递归再输出:从头到尾
//如果是先输出再递归:从尾到头
cout<<x<<" "<<y<<" "<<z<<endl;
};
pr(pr,pos[0],pos[1],pos[2]);
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
const int INF=0x3f3f3f3f;
const int N=3e2+10;
//BFS最短路+记路线
array<int,3> c,w;
int t;
void solve(){
cin>>c[0]>>c[1]>>c[2]>>w[0]>>w[1]>>w[2]>>t;
//记最短路
vector dp(c[0] + 1, vector(c[1] + 1, vector<int>(c[2] + 1, -1)));
//记路线
vector last(c[0] + 1, vector(c[1] + 1, vector<array<int, 3>>(c[2] + 1, {-1, -1, -1})));
queue< array<int,3> > q;
dp[w[0]][w[1]][w[2]]=0;
q.push({w[0],w[1],w[2]});
while(q.size()){
auto tt=q.front();
q.pop();
//互相倒
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(i==j) continue;
int d=min(tt[i],c[j]-tt[j]);
auto tmp=tt;
tmp[i]-=d;
tmp[j]+=d;
if(dp[tmp[0]][tmp[1]][tmp[2]]==-1){
//记录长度
dp[tmp[0]][tmp[1]][tmp[2]]=dp[tt[0]][tt[1]][tt[2]]+1;
//记录路线
last[tmp[0]][tmp[1]][tmp[2]]=tt;
q.push(tmp);
}
}
}
//倒出最小值
int minn=1e9;
//注意这里!如果一个杯子已经倒空->不需要再计算!
for(int i=0;i<3;i++) if(tt[i]) minn=min(minn,tt[i]);
for(int i=0;i<3;i++){
if(tt[i]==minn){
auto tmp=tt;
tmp[i]=0;
if(dp[tmp[0]][tmp[1]][tmp[2]]==-1){
//记录长度
dp[tmp[0]][tmp[1]][tmp[2]]=dp[tt[0]][tt[1]][tt[2]]+1;
//记录路线
last[tmp[0]][tmp[1]][tmp[2]]=tt;
q.push(tmp);
}
}
}
}
//找所有满足条件的最小值
int cnt=1e9;
array<int,3> pos;
for(int i=0;i<=c[0];i++){
for(int j=0;j<=c[1];j++){
for(int k=0;k<=c[2];k++){
if(i==t || j==t || k==t){
if(dp[i][j][k]!=-1){
if(cnt>dp[i][j][k]){
cnt=dp[i][j][k];
pos={i,j,k};
}
}
}
//cout<<cnt<<endl;
}
}
}
if(cnt==1e9){
cout<<"-1"<<endl;
return;
}
else{
//输出路线:lambda函数递归(学习!)
cout<<cnt<<endl;
auto pr=[&](auto self,int x,int y,int z)->void{
if(x==w[0] && y==w[1] && z==w[2]) return;
auto it=last[x][y][z];
//对自身的递归:self
self(self,it[0],it[1],it[2]);
//先递归再输出:从头到尾
//如果是先输出再递归:从尾到头
cout<<x<<" "<<y<<" "<<z<<endl;
};
pr(pr,pos[0],pos[1],pos[2]);
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}