3 条题解

  • 1
    @ 2023-10-27 21:41:07

    更好的阅读体验

    具体思路

    fi,xf_{i,x} 表示 ii 个盘子从 xx 柱子出发的步数。

    gi,xg_{i,x} 表示 ii 个盘子从 xx 柱子出发到哪个柱子。

    y=gi1,xy=g_{i-1,x}z=6xyz=6-x-y

    其中,yy 代表将前 i1i-1 个盘子从 xx 柱子移到的柱子,zz 代表剩下的那个柱子。

    分类讨论。

    • gi1,y=zg_{i-1,y}=z,表示 i1i-1 个盘子先从 xx 移到 yy,第 ii 个盘子从 xx 移到 zzi1i-1 个盘子再从 yy 移回 zz

    fi,x=fi1,x+1+fi1,y,gi,x=zf_{i,x}=f_{i-1,x}+1+f_{i-1,y},g_{i,x}=z

    • gi1,y=xg_{i-1,y}=x,表示 i1i-1 个盘子先从 xx 移到 yy,第 ii 个盘子从 xx 移到 zzi1i-1 个盘子再从 yy 移回 xx,第 ii 个盘子从 zz 移到 yyi1i-1 个盘子再从 xx 移回 yy

    $f_{i,x}=f_{i-1,x}+1+f_{i-1,y}+1+f_{i-1,x},g_{i,x}=y$。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=31,M=4;
    int g[N][M],vis[M];LL f[N][M];
    int main(){
    	int n;scanf("%d",&n);
    	for(int i=1;i<=6;i++){
    		char op[10];scanf("%s",op+1);
    		int x=op[1]-'A'+1,y=op[2]-'A'+1;
    		if(vis[x])continue;
    		vis[x]=1;
    		f[1][x]=1,g[1][x]=y;
    	}
    	for(int i=2;i<=n;i++){
    		for(int x=1;x<=3;x++){
    			int y=g[i-1][x],z=6-x-y;
    			if(g[i-1][y]==z){
    				f[i][x]=f[i-1][x]+1+f[i-1][y];
    				g[i][x]=z;
    			}
    			if(g[i-1][y]==x){
    				f[i][x]=f[i-1][x]+1+f[i-1][y]+1+f[i-1][x];
    				g[i][x]=y;
    			}
    		}
    	}
    	printf("%lld\n",f[n][1]);
    	return 0;
    }
    
    • 0
      @ 2022-8-11 20:58:10
      #include<stdio.h>
      #include<math.h>
      typedef long long ll;
      char a[4];
      int s[9],p,n,i=6;
      ll f(int x){
      	if(x==1)return (ll)2*pow(3,n-1)-1;
      	if(x)return (ll)pow(2,n)-1;
      	return (ll)pow(3,n-1);
      }
      int main(){
      	scanf("%d",&n);
      	while(i--)scanf("%s",a),s[(a[0]-'A')*3+a[1]-'A']=i;
      	if(s[1]>s[2]){
      		if(s[5]<s[3])p=1;
      		else if(s[6]>s[7])p=2;
      	}else if(s[7]<s[6])p=1;
      	else if(s[3]>s[5])p=2;
      	printf("%lld",f(p));
      	return 0;
      }
      
      • 0
        @ 2021-12-27 15:07:12

        分析

        首先,如果不按照题目中的限制来,那么最优操作步数为 hn=2×hn1+1h_n=2\times h_{n-1}+1,其中 h1=1h_1=1

        大胆猜测这道题的答案也满足一个 hn=k×hn1+bh'_n=k\times h'_{n-1}+b 的递推关系。

        模拟出前三项,计算出 kkbb 最后递推即可。

        实现

        #include <cstdio>
        #include <cstring>
        #include <iostream>
        #include <stack>
        #define LL long long
        
        using namespace std;
        
        int n, f[10], t[10];
        LL ans[50];
        stack<int> st[5];
        
        int simulate(int n) {
          for (int i = 1; i <= 3; i++)
            while (!st[i].empty()) st[i].pop();
          for (int i = n; i >= 1; i--) st[1].push(i);
          int ans = 0, l = 0;
          while (true) {
            ans++;
            for (int i = 1; i <= 6; i++)
              if (!st[f[i]].empty() && st[f[i]].top() != l &&
                  (st[t[i]].empty() || st[f[i]].top() < st[t[i]].top())) {
                l = st[f[i]].top(), st[f[i]].pop(), st[t[i]].push(l);
                break;
              }
            for (int i = 1; i <= 3; i++)
              if (st[i].size() == n) return ans;
          }
        }
        
        int main() {
          cin >> n;
          for (int i = 1; i <= 6; i++) {
            char x, y;
            cin >> x >> y;
            f[i] = x - 'A' + 1, t[i] = y - 'A' + 1;
          }
          ans[1] = simulate(1), ans[2] = simulate(2), ans[3] = simulate(3);
          int k = (ans[3] - ans[2]) / (ans[2] - ans[1]), b = ans[2] - ans[1] * k;
          for (int i = 4; i <= n; i++) ans[i] = ans[i - 1] * k + b;
          return cout << ans[n] << endl, 0;
        }
        
        
        • 1

        信息

        ID
        1019
        时间
        1000ms
        内存
        256MiB
        难度
        5
        标签
        (无)
        递交数
        23
        已通过
        14
        上传者