题目链接

题目分析

首先,看到题目中的左移右移之后再异或,我们自然可以想到在移动的过程中字符串的一段前缀和后缀不会改变,考虑通过这个性质逐位还原。

因为异或 0 不会改变原本的值,所以我们可以找到整个字符串的第一个 1,把这个位置即为 \(i\),用它右移异或其他与另一字符串不同值的位置,因为我们每次异或的副作用只作用在那一位之后,所以经过这个操作可以保证第 \(i+1\) 到第 \(n\) 位被全部还原。

那前面部分的不同值呢,将其拉到前面异或会导致其他因素改变,如果拉最后一个则有可能只有这一个 1 而自己也需要改变,注意到如果小于 \(i\) 的所有位置都为 0 就好操作的多,只需复制前面的操作,改变一下方向把这个 1 往前推即可,那么我们如何将所有情况转化为这种情况呢?

其实很简单,记一开始的两个字符串第一个 1 的位置分别为 \(j\) 和 \(k\),\(j\leq k\) 则无需操作,否则把一个后面的 1 拉过来与这位异或一下即可,可以发现情况一最多操作 \(n\) 次,情况二最多 \(n-k+1\) 次。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
bool jud(int n,string s){
for(int i=0;i<n;i++) if(s[i]!='0') return false;
return true;
}
int find(int n,string s){
for(int i=0;i<n;i++) if(s[i]=='1') return i;
}
char change(char x){
return x=='0'?'1':'0';
}
string ope(int n,string s,int k){
string tmp=s;
for(int i=0;i<n;i++){
int ti=i+k;
if(ti<0 || ti>=n) continue;
if(tmp[ti]=='1') s[i]=change(s[i]);
}
return s;
}
int opt[1000001],tot=0;
int main(){
int t;
cin>>t;
while(t--){
int n;tot=0;
string a,b;
cin>>n>>a>>b;
if((jud(n,a) && !jud(n,b))||(!jud(n,a) && jud(n,b))){
cout<<-1<<endl;
continue;
}
if(a==b){cout<<0<<endl;continue;}
int j=find(n,a),k=find(n,b);
if(j>k) {opt[++tot]=j-k;a=ope(n,a,j-k);j=k;}
for(int i=j+1;i<n;i++) if(a[i]!=b[i]){opt[++tot]=j-i;a=ope(n,a,j-i);}
int pl=0;
for(int i=n;i>0;i--) if(a[i]=='1') {pl=i;break;}
for(int i=j;i>=0;i--)if(a[i]!=b[i]){opt[++tot]=pl-i;a=ope(n,a,pl-i);}
cout<<tot<<endl;
for(int i=1;i<=tot;i++) cout<<opt[i]<<' ';
cout<<endl;
}
}

CF1789D Serval and Shift-Shift-Shift 题解的更多相关文章

  1. Triple Shift

    来源:Atcoder ARC 136 B - Triple Shift (atcoder.jp) 题解:这道题我们不可能去硬模拟(大多数这种题都不能这样去模拟的),然后我们就要去发现特性, 发现把 a ...

  2. Javascript——arguments的shift问题谈方法“借用”

    今天本来运行了打算这样的方法 arguments.shift() (shift方法是删除数组的第一个元素,例如var arr=[1,2,3,4,5]执行var a=arr.shift();之后,a的值 ...

  3. 小tip:关于typeof,instanceof,toString(),valueOf(),toLocaleString(),join(),reverse(),sort(),pop(),push(),shift(),unshift()

    typeof:用于检测一个变量是否是基本数据类型.instanceof用于检测某引用对象是什么类型的对象. var s = "Nicho"; var b = true; var n ...

  4. (转)Eclipse快捷键大全,导包快捷键:ctrl+Shift+/

    Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当 ...

  5. shell编程控制结构:expr、let、for、while、until、shift、if、case、break、continue、功能、select

    1.expr计算整数变量值 s=`expr 2 + 3` 运算符号和參数之间要有空格分开: 2.let命令 let s=(2+3)*4 echo $s 3.for语句 for 变量 in 列表 do ...

  6. C#-判断Shift,Alt,Ctrl是否被按下,确定所按下的组合键

    在创建接受用户击键的应用程序时,您还可能希望监视 SHIFT.ALT 和 CTRL 键等组合键.当一个组合键与其他键同时按下,或在单击鼠标的同时按下时,您的应用程序能够做出适当响应:字母 S 可能仅导 ...

  7. Eclipse快捷键大全,导包快捷键:ctrl+Shift+/【转】

    Ctrl+Shift+L 显示所有快捷键 Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复 ...

  8. 《Advanced Bash-scripting Guide》学习(十一):shift的用法

    本文所选的例子来自于<Advanced Bash-scripting Gudie>一书,译者 杨春敏 黄毅 Example 4-7 使用shift #!/bin/bash #使用shift ...

  9. js开发:数组的push()、pop()、shift()和unshift()(转)

    js开发:数组的push().pop().shift()和unshift() 2017-05-18 11:49 1534人阅读 评论(0) 收藏 举报  分类: javascript开发(22)  版 ...

  10. 处理回车提交、ctrl+enter和shift+enter都不提交->textarea正常换行

    <input type="textarea" @on-keypress="handlerMultiEnter"> handlerMultiEnter ...

随机推荐

  1. 即构SDK10月迭代:新增多款语音音效、外部采集码流控制及Android SDK 最低支持操作系统版本调整

    即构SDK10月迭代内容来喽~~~ 本月调整了Android SDK 最低支持的操作系统版本,新增了流删除回调原因, 4种变音效果和外部采集码流控制,同时还对登录房间.媒体播放器以及第三方库进行了优化 ...

  2. Hexo博客Next主题相册搭建

    参考文章,小红鸡 参考文章,主题美化 效果展示:相册 在blog文件夹/source下创建photos文件夹,在photos文件夹创建index.md文件,编辑index.md文件,写入以下代码: & ...

  3. boinc使用笔记

    安装 yum install -y epel-release yum install -y boinc-client boinc-manager 启动 在图形界面开启终端 boinc boincmgr

  4. 关于bzoj3306(树)的一些反思

    1.加零大法好,用好没烦恼 2.不要瞎开long long 3.万物皆可变成wa 4.如果超时,试图把循环中中的东西拉到外面来

  5. QPushButton按钮的使用

    1 import sys 2 from PyQt5.QtCore import * 3 from PyQt5.QtGui import * 4 from PyQt5.QtWidgets import ...

  6. 钟表练习 html+css实现

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. 文心一言 VS 讯飞星火 VS chatgpt (69)-- 算法导论6.5 8题

    八.HEAP-DELETE(A,i)操作能够将结点 i 从堆 A 中删除.对于一个包含 n个元素的堆,请设计一个能够在 O(lgn)时间内完成的 HEAP-DELETE 操作. 文心一言: 要在 O( ...

  8. 《CUDA编程:基础与实践》读书笔记(2):CUDA内存

    1. 全局内存 核函数中的所有线程都能够访问全局内存(global memory).全局内存的容量是所有设备内存中最大的,但由于它没有放在GPU芯片内部,因此具有相对较高的延迟和较低的访问速度,cud ...

  9. __wakeup()魔术方法绕过(CVE-2016-7124)

    __wakeup()魔术方法绕过(CVE-2016-7124) 漏洞简介 在php反序列化数据过程中,如果类中存在__wakeup方法,调用 unserilize() 方法前则先调用__wakeup方 ...

  10. linux 查找目录中的大文件

    find是Linux系统中常用的文件查找命令.它可以在文件系统中查找指定条件的文件,并执行相应的操作.语法格式如下: find [pathname] [options] pathname: 指定查找的 ...