zoukankan      html  css  js  c++  java
  • [CF936C] Lock Puzzle

    前言

    终于自己做出来一道构造题了!

    题目

    CF

    洛谷

    讲解

    (nle2000),限制(6100),我们不难猜测有一个(3n)的做法

    猜测是一个字母一个字母地使其有序,每个字母有(3)次机会到指定位置

    通过一顿乱搞,发现如下方法:

    图中蓝色箭头为之前已经排好的有序的字母(目标串的前缀),黑点为我们要放到蓝色箭头右边的字母

    其余颜色的箭头为其它无序字母

    箭头的方向代表了是否反转

    建议结合代码食用

    判断无解就是判断是否字母数不同

    代码

    大常数代码

    const int MAXN = 2005;
    int n;
    char s[MAXN],t[MAXN],tmp[MAXN]; 
    int cnt[256];
    int ans[MAXN * 3],anstot;
    
    bool check()
    {
    	for(int i = 1;i <= n;++ i) if(s[i] != t[i]) return 0;
    	return 1;
    }
    void Add(int x) 
    {
    	if(!x) return;
    	ans[++anstot] = x;
    	for(int i = n-x+1;i <= n;++ i) tmp[n-i+1] = s[i];
    	for(int i = 1;i <= n-x;++ i) tmp[i+x] = s[i];
    	for(int i = 1;i <= n;++ i) s[i] = tmp[i];
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read();
    	scanf("%s%s",s+1,t+1);
    	for(int i = 1;i <= n;++ i) cnt[s[i]]++;
    	for(int i = 1;i <= n;++ i)
    	{
    		cnt[t[i]]--;
    		if(cnt[t[i]] < 0)
    		{
    			printf("-1");
    			return 0;
    		}
    	}
    	for(int i = 1;i <= n;++ i)
    	{
    		if(check()) break;//删了更快的剪枝
    		int ID = 0;
    		for(int j = 1;!ID;++ j)
    			if(s[j] == t[i])
    				ID = j;
    		//寻找“黑点”
    		Add(n-ID);
    		Add(1);
    		Add(n);
    		//使用三次转换机会
    	}
    	Put(anstot,'
    ');
    	for(int i = 1;i <= anstot;++ i) Put(ans[i],' ');
    	return 0;
    }
    
  • 相关阅读:
    UVA 10970 Big Chocolate
    HBuilder 安装uviewui2.0
    域名访问配置支持ipv6
    SSIS学习视频(SQL Server 2008)
    碰到MySQL无法启动1067错误问题
    对存储过程进行加密和解密(SQL 2008/SQL 2012)
    脚本文件比较工具WinMerge
    通过SQL绘制杨辉三角
    通用分页存储过程(SQL Server 2005)
    重新组织和重新生成索引sp_RefreshIndex
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14175774.html
Copyright © 2011-2022 走看看