Lock Puzzle 【CodeForces - 936C】【思维】

题目链接

Welcome to another task about breaking the code lock! Explorers Whitfield and Martin came across an unusual safe, inside of which, according to rumors, there are untold riches, among which one can find the solution of the problem of discrete logarithm!

Of course, there is a code lock is installed on the safe. The lock has a screen that displays a string of n lowercase Latin letters. Initially, the screen displays string s. Whitfield and Martin found out that the safe will open when string t will be displayed on the screen.

The string on the screen can be changed using the operation «shift x». In order to apply this operation, explorers choose an integer x from 0 to n inclusive. After that, the current string p = αβ changes to βRα, where the length of β is x, and the length of α is n - x. In other words, the suffix of the length x of string p is reversed and moved to the beginning of the string. For example, after the operation «shift 4» the string «abcacb» will be changed with string «bcacab », since α = ab, β = cacb, βR = bcac.

Explorers are afraid that if they apply too many operations «shift», the lock will be locked forever. They ask you to find a way to get the string t on the screen, using no more than 6100 operations.

Input
The first line contains an integer n, the length of the strings s and t (1 ≤ n ≤ 2 000).

After that, there are two strings s and t, consisting of n lowercase Latin letters each.

Output
If it is impossible to get string t from string s using no more than 6100 operations «shift», print a single number  - 1.

Otherwise, in the first line output the number of operations k (0 ≤ k ≤ 6100). In the next line output k numbers xi corresponding to the operations «shift xi» (0 ≤ xi ≤ n) in the order in which they should be applied.

解题思路

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;

const int N=5005;
char s[N],t[N],n;
int n;
long long ans[N*10],k=0;

void re(int x)
{
    if(x==0) return ;
    char a1[N],b1[N];
    for(int i=n-1,j=1;j<=x;i--,j++)
        a1[j]=s[i];
    for(int i=0;i<n-x;i++)
        b1[i]=s[i];
    int ss=0;
    for(int i=1;i<=x;i++)
        s[ss++]=a1[i];
    for(int i=0;i<n-x;i++)
        s[ss++]=b1[i];
    ans[++k]=x;
}
int main()
{
    scanf("%d%s%s", &n, s, t);
    
    for(int i=0;i<n;i++)
    {
        int j=0;
        while(j<n-i&&s[j]!=t[i]) j++;
        if(j==n-i)
        {
            printf("-1\n");
            return 0;
        }
        re(n-j-1);
        re(1);
        re(n);
    }
    printf("%d\n",k);
    for(int i=1;i<=k;i++)
        printf("%d ",ans[i]);
    printf("\n");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用分支限界算法求解15-puzzle问题的C语言代码: ``` #include<stdio.h> #include<queue> #include<algorithm> #include<cstring> #define MAXN 16 using namespace std; int goal[MAXN]={ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15 }; int dx[4]={-1,0,1,0}; int dy[4]={0,1,0,-1}; struct node{ int state[MAXN]; int x,y; //空格的位置 int f; //f=g+h int g; //g:从起点到该点的距离 int h; //h:该点到目标状态的距离 char path[MAXN]; bool operator<(const node& a)const{ return f>a.f; } }; int h(int *state){ int sum=0; for(int i=0;i<16;i++){ if(state[i]==0)continue; int x1=i/4,y1=i%4; int x2=(state[i]-1)/4,y2=(state[i]-1)%4; sum+=abs(x1-x2)+abs(y1-y2); } return sum; } void print_path(char *path){ for(int i=0;path[i];i++){ printf("%c",path[i]); } printf("\n"); } bool is_goal(int *state){ return memcmp(state,goal,sizeof(goal))==0; } void move(int *state,int x,int y,int tx,int ty){ swap(state[x*4+y],state[tx*4+ty]); } int main(){ int state[MAXN]; memset(state,0,sizeof(state)); for(int i=0;i<16;i++){ scanf("%d",&state[i]); if(state[i]==0)state[i]=16; if(state[i]==16)state[i]=0; //将空格视为0 } node n; memcpy(n.state,state,sizeof(state)); n.g=0; n.h=h(state); n.f=n.g+n.h; n.x=find(state,state+MAXN,0)-state; n.y=n.x%4; priority_queue<node> q; q.push(n); while(!q.empty()){ node u=q.top(); q.pop(); if(is_goal(u.state)){ print_path(u.path); break; } int x=u.x,y=u.y; for(int i=0;i<4;i++){ int tx=x+dx[i],ty=y+dy[i]; if(tx<0||tx>=4||ty<0||ty>=4)continue; node v=u; move(v.state,x,y,tx,ty); v.x=tx; v.y=ty; v.g=u.g+1; v.h=h(v.state); v.f=v.g+v.h; v.path[v.g-1]="urdl"[i]; q.push(v); } } return 0; } ``` 这个程序使用了分支限界算法来解决15 Puzzle问题,使用了曼哈顿距离作为启发函数来帮助加速搜索。在搜索过程中,使用了优先队列来维护候选节点,并使用了剪枝来避免重复搜索和搜索无效的分支。最后,程序输出解决问题的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值