记录编号 | 182872 | 评测结果 | AAAAAAAAAA | ||
---|---|---|---|---|---|
题目名称 | [CEPC 2003] 骰子游戏 | 最终得分 | 100 | ||
用户昵称 | 是否通过 | 通过 | |||
代码语言 | C++ | 运行时间 | 0.880 s | ||
提交时间 | 2015-08-29 10:37:38 | 内存使用 | 2.01 MiB | ||
#include<cstdio> #include<deque> #include<iostream> #include<cstring> #include<cmath> using namespace std; typedef long long LL; const LL maxn=LL(1e17); const int SIZEH=4,SIZENUM=6; const int SIZEC=20; int L[7]; int x1,x2; int y3,y2; LL f[3000]; int opposite[7]={0};//第i面的对面是什么 int id[5][SIZENUM+1][SIZENUM+1]={0};//状态编号,分别是行,正面,上面 int N;//总状态数 int C;//c的状态数 int S;//起始状态 int onleft[40][40]={0}; deque<pair<int,int> > c[3000]; pair<int,pair<int,int> > state[720]; deque<int> T; void check_u(int u) { int tem=u%N; if(u==0) u=N; cout<<(u-1)/N<<" "; cout<<state[tem].first<<" "<<state[tem].second.first<<" "<<state[tem].second.second<<endl;; } class miku { public: int n,m; LL s[160][160]; miku() { n=m=0; for(int i=0;i<=144;i++) for(int j=0;j<=144;j++) s[i][j]=maxn; } void print() { cout<<n<<" "<<m<<endl; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cout<<s[i][j]<<" ";//check_u(j); } cout<<endl; } cout<<endl; } void make(int a) { n=m=a; for(int i=1;i<=n;i++) s[i][i]=0; } }; inline miku operator * (miku a,miku b) { miku c; c.n=a.n;c.m=b.m; for(int i=1;i<=c.n;i++) for(int j=1;j<=c.m;j++) { for(int k=1;k<=a.m;k++) c.s[i][j]=min(c.s[i][j],a.s[i][k]+b.s[k][j]); } return c; } inline miku quickpow(miku a,LL b) { miku re; re.make(a.n); //re.print(); //cout<<b<<endl; while(b) { if(b&1) re=re*a; b>>=1;a=a*a; } //re.print(); return re; } void check_c() { for(int u=1;u<=C;u++) { check_u(u); cout<<"to:"<<endl; for(int i=0;i<c[u].size();i++) { check_u(c[u][i].first); cout<<c[u][i].second<<endl; } cout<<endl; } } void check_f() { check_u(S); for(int i=1;i<=N;i++) {check_u(i+8*N);cout<<" "<<f[i+8*N]<<endl;} } int left(int j,int k) { return onleft[j][k]; } int right(int j,int k) { return opposite[onleft[j][k]]; } void make_c() { C=SIZEC*N; for(int x=0;x<SIZEC;x++) for(int y=1;y<=4;y++) for(int fr=1;fr<=6;fr++)//枚举正面 for(int up=1;up<=6;up++) { if(fr==up||fr==opposite[up]) continue; int u=id[y][fr][up]+x*N;; if(x>0) c[u].push_back(make_pair(id[y][fr][right(fr,up)]+(x-1)*N,L[right(fr,up)])); if(x<SIZEC-1) c[u].push_back(make_pair(id[y][fr][left(fr,up)]+(x+1)*N,L[left(fr,up)])); if(y>1) c[u].push_back(make_pair(id[y-1][up][opposite[fr]]+x*N,L[opposite[fr]])); if(y<4) c[u].push_back(make_pair(id[y+1][opposite[up]][fr]+x*N,L[fr])); } //check_c(); } void prepare() { opposite[1]=6;opposite[6]=1; opposite[2]=5;opposite[5]=2; opposite[4]=3;opposite[3]=4; if(x1>x2)//镜像反转 { swap(L[2],L[5]); swap(L[3],L[4]); swap(x1,x2); y3=4+1-y3;y2=4+1-y2; } if(x1!=0) x2-=x1;x1=0; N=0; for(int i=1;i<=4;i++) for(int j=1;j<=6;j++) for(int k=1;k<=6;k++) { if(j==k||j==opposite[k]) continue; id[i][j][k]=++N; state[N]=make_pair(i,make_pair(j,k)); } S=id[y3][2][1]; onleft[1][2]=4;onleft[1][3]=2; onleft[2][1]=3;onleft[2][3]=6; onleft[3][1]=5;onleft[3][2]=1; for(int i=1;i<=6;i++) for(int j=1;j<=6;j++) { if(i==j||i==opposite[j]) continue; if(onleft[i][j]) continue; else if(onleft[i][opposite[j]]) onleft[i][j]=opposite[onleft[i][opposite[j]]]; else if(onleft[opposite[i]][j]) onleft[i][j]=opposite[onleft[opposite[i]][j]]; else if(onleft[opposite[i]][opposite[j]]) onleft[i][j]=onleft[opposite[i]][opposite[j]]; } make_c(); for(int i=1;i<=6;i++) for(int j=1;j<=6;j++) { if(i==j||i==opposite[j]) continue; T.push_back(id[y2][i][j]); } } void spfa(int s,int n) { bool inq[3000]={0}; deque<int> Q; for(int i=1;i<=n;i++) f[i]=maxn; inq[s]=1;f[s]=0;Q.push_back(s); //check_c(); while(!Q.empty()) { int x=Q.front();Q.pop_front();inq[x]=0; for(int i=0;i<c[x].size();i++) { pair<int,int> v=c[x][i]; if(f[x]+v.second<f[v.first]) { f[v.first]=f[x]+v.second; if(!inq[v.first]) { Q.push_back(v.first); inq[v.first]=1; } } } } } void get(miku &I,miku &D) { I.n=1;I.m=N; int tem=SIZEC/2-1; //cout<<N<<endl; spfa(S+tem*N,C); D.m=D.n=N; //for(int i=1;i<=C;i++) cout<<f[i]<<endl; for(int i=1;i<=N;i++) I.s[1][i]=f[i+tem*N]; for(int i=1;i<=N;i++) { spfa(i,C); for(int j=1;j<=N;j++) D.s[i][j]=f[j+N]; } } void work() { miku I,D; get(I,D); //D.print(); I=I*quickpow(D,x2-x1); LL ans=maxn; for(int i=0;i<T.size();i++) { ans=min(I.s[1][T[i]],ans); } cout<<ans; } int main() { freopen("dicecontest.in","r",stdin); freopen("dicecontest.out","w",stdout); for(int i=1;i<=6;i++) scanf("%d",&L[i]); scanf("%d%d%d%d",&x1,&y3,&x2,&y2);//lld prepare(); //cout<<1<<endl; work(); return 0; }