4位开锁<dfs>

题意:
有一个四位密码的锁,每一位是1~9的密码,1跟9相连。并且相邻的连个密码位可以交换。每改变一位耗时1s,给出锁的当前状态和密码,求最少解锁时间。
思路:
用bfs枚举出所有相邻交换的情况,并记录时间,然后每一位与密码比较,得出最少时间。注意输入的是一个数字,要把每一位提取出来。
代码:


#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int visit[4]={0},ss,a[4],b[4];  //visit记录a[i]是否被访问,ss用来记录暴力过程中的最小值
int cmp(int s)  //这个是用来记录从当前这样的状态不左右移动最少要多少次
{
    int i,sum,aa[4]={s/1000,s/100%10,s/10%10,s%10};  //因为进来的是一个数字,所以用数组把它阉了,嘿嘿
    for(i=sum=0;i<4;i++)  //一位一位的开锁
    {
        if(abs(aa[i]-b[i])<5)sum+=abs(aa[i]-b[i]);
        else sum+=9-abs(aa[i]-b[i]);
    }
    return sum;
}
void dfs(int sum,int s)  //dfs里面进来的sum是当前的这个合成的数字,也就是不停移动得到的数组,s是记录移动次数
{
    int i;
    if(sum>999)  //当sum>999也就是说sum是一个四位数时说明新的那个开锁初始状态OK了
    {
        i=cmp(sum)+s;  //这时把sum和数组b开锁的次数和用s记录的移动的次数记录下来
        if(i<ss)ss=i;  //比较,ss记录最小开锁操作
        return;
    }
    for(i=0;i<4;i++)
    {
        if(!visit[i])
        {
            visit[i]=1;
            dfs(sum*10+a[i],s++);  //要是你聪明,会看到这里的一个重要的步骤,就是s++,别小看了,这说明下一次再在for循环里面取数就是在这次的数移动一位得到的,本体就是这个才是重点呢
            visit[i]=0;
        }
    }
}
int main (void)
{
    int i,j,n,m,t;
    cin>>t;
    while(t--&&cin>>n>>m)
    {
        for(i=3,j=1;i>=0;i--,j*=10)
        {
            a[i]=n/j%10;
            b[i]=m/j%10;
        }
        ss=99999;
        dfs(0,0);
        cout<<ss<<endl;

    }
return 0;
}
package com.example.card.utils; import android.os.Handler; import android.os.Looper; import android.util.Log; import com.vi.vioserial.COMSerial; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 基于队列管理和状态机实现异步非阻塞处理,确保指令顺序执行且避免阻塞: * <p> * 任务队列:使用ConcurrentLinkedQueue存储开锁请求 * <p> * 状态机:定义IDLE/SENDING/WAITING_RESPONSE三种状态 * <p> * 超时机制:Handler实现超时检测防止阻塞 * <p> * 结果解析:通过正则匹配处理串口返回数据 * <p> * 线程安全:AtomicBoolean保证状态变更原子性 */ public class LockManager { private static String mSeialPort;//串口 // 状态定义 private enum State {IDLE, SENDING, WAITING_RESPONSE} // 超时时间(毫秒) private static final long RESPONSE_TIMEOUT = 3000; // 状态机控制 private State currentState = State.IDLE; private final AtomicBoolean isProcessing = new AtomicBoolean(false); private final Handler mainHandler = new Handler(Looper.getMainLooper()); // 超时任务引用 private Runnable timeoutRunnable; // 响应状态标志 (volatile保证多线程可见性) private volatile boolean responseReceived = false; // 任务队列 private final ConcurrentLinkedQueue<LockTask> taskQueue = new ConcurrentLinkedQueue<>(); // 结果解析正则(匹配示例:0D241900500001A0313233...) private static final Pattern RESPONSE_PATTERN = Pattern.compile("^0D241900500001([A-F0-9]{2}).*ED0D0A$"); // 单例模式 private static volatile LockManager instance; // 当前处理的任务对象 private LockTask currentTask; // 获取当前任务 private LockTask getCurrentTask() { return currentTask; } public static LockManager getInstance(String seialPort) { mSeialPort = seialPort; if (instance == null) { synchronized (LockManager.class) { if (instance == null) { instance = new LockManager(); } } } return instance; } // 开锁任务封装 private static class LockTask { final String lockId; final String hexCommand; final LockCallback callback; LockTask(String lockId, String hexCommand, LockCallback callback) { this.lockId = lockId; this.hexCommand = hexCommand; this.callback = callback; } } // 回调接口 public interface LockCallback { void onOpened(String lockId); void onFailure(String lockId, String error); void onClosed(String lockId ); void onTimeout(String lockId); } // 添加开锁任务 public void unlock(String lockId, String hexCommand, LockCallback callback) { taskQueue.offer(new LockTask(lockId, hexCommand, callback)); processNextTask(); } // 任务处理器 private void processNextTask() { if (!isProcessing.compareAndSet(false, true)) return; LockTask task = taskQueue.poll(); if (task == null) { isProcessing.set(false); return; } currentState = State.SENDING; sendLockCommand(task); } // 发送开锁指令(修改后) private void sendLockCommand(LockTask task) { this.currentTask = task; try { // 重置状态标志 responseReceived = false; // 取消之前的超时任务(如果有) cancelTimeout(); // 发送指令 COMSerial.instance().sendHex(mSeialPort, task.hexCommand); currentState = State.WAITING_RESPONSE; // 创建并保存超时任务 timeoutRunnable = () -> { // 双重检查:1.检查状态 2.检查响应标志 if (currentState == State.WAITING_RESPONSE && !responseReceived) { handleTimeout(task); } }; // 提交超时检测 mainHandler.postDelayed(timeoutRunnable, RESPONSE_TIMEOUT); } catch (Exception e) { task.callback.onFailure(task.lockId, "Send error: " + e.getMessage()); completeTask(); } } // 处理串口响应(修改后) public void handleSerialResponse(String response) { if (currentState != State.WAITING_RESPONSE) return; LockTask task = getCurrentTask(); if (task == null) return; // 关键步骤1:立即设置响应标志 responseReceived = true; // 关键步骤2:立即取消超时任务 cancelTimeout(); // 关键步骤3:处理响应(状态机不变) Matcher matcher = RESPONSE_PATTERN.matcher(response); if (!matcher.find()) return; String statusCode = matcher.group(1); if ("A0".equals(statusCode)) { task.callback.onOpened(task.lockId); } else if ("F0".equals(statusCode)) { task.callback.onClosed(task.lockId ); } else { task.callback.onFailure(task.lockId, "Unknown status: " + statusCode); } completeTask(); } // 新增:超时取消方法 private void cancelTimeout() { if (timeoutRunnable != null) { mainHandler.removeCallbacks(timeoutRunnable); timeoutRunnable = null; } } // 超时处理 private void handleTimeout(LockTask task) { if (currentState == State.WAITING_RESPONSE) { task.callback.onTimeout(task.lockId); completeTask(); } } // 完成任务(修改后) private void completeTask() { // 确保清理超时任务 cancelTimeout(); // 重置状态 responseReceived = false; this.currentTask = null; currentState = State.IDLE; isProcessing.set(false); // 处理下一个任务 processNextTask(); } // 资源释放(修改后) public void release() { // 清理所有待处理任务 cancelTimeout(); mainHandler.removeCallbacksAndMessages(null); taskQueue.clear(); } // 在任务处理过程中获取当前任务信息 public void logTaskStatus() { LockTask task = getCurrentTask(); if (task != null) { Log.d("LockManager", "处理中的任务: " + task.lockId); } } // 紧急停止当前任务 public void emergencyStop() { LockTask task = getCurrentTask(); if (task != null) { task.callback.onFailure(task.lockId, "操作被强制中断"); completeTask(); } } } // 批量开锁请求 String[] locks = {"LOCK_001", "LOCK_002", "LOCK_003"}; for (String lockId : locks) { lockManager.unlock(lockId, generateHexCommand(lockId), new LockManager.LockCallback() { @Override public void onOpened(String lockId) { runOnUiThread(() -> PopTip.show(lockId + " 已开锁")); } @Override public void onClosed(String lockId) { runOnUiThread(() -> PopTip.show(lockId + " 已关门")); } @Override public void onFailure(String lockId, String error) { runOnUiThread(() -> PopTip.show(lockId + " 异常" + error)); } @Override public void onTimeout(String lockId) { runOnUiThread(() -> PopTip.show(lockId + " 超时")); } }); } 批量执行3次开锁,但实际只完成了两次,而且再点击按钮重新执行时就无效了
最新发布
08-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值