第一行输入N,第二行输入N个数字,只包含0,1,2
输出字符串要移几位才能解开密码,如果无论移位多少次都解不开密码,输出-1
5 02120 5 02120
1 1
#include<string>
(765)#include<queue>
#include<iostream>
(720)#include<algorithm>
#include<unordered_map>
using namespace std;
bool find2012(string li, int start, int end) {
for(int i=start; i<=end; ++i)
if(li[i]==50 && li[i+1]==48 && li[i+2]==49 && li[i+3]==50)
return true;
return false;
}
int BFS(string li, int size) {
unordered_map<string, int> st;
int count=0, start, end;
queue<string> q;
q.push(li);
st[li]=1;
while(!q.empty()) {
int q_size=q.size();
while(q_size--) {
string tmp=q.front();
q.pop();
if(count==0 && find2012(tmp, 0, size-4)) return 0;
else {
for(int i=0; i<size-1; ++i) {
swap(tmp[i], tmp[i+1]);
start=max(0, i-3);
end=min(size-1, i+1);
if(st.find(tmp) == st.end()) {
if(find2012(tmp, start, end)) return count+1;
q.push(tmp);
st[tmp]=1;
}
swap(tmp[i], tmp[i+1]);
}
}
}
++count;
}
return -1;
}
int main() {
int n;
string li;
while(cin>>n) {
cin>>li;
if(count(li.begin(), li.end(), '2')<2 || count(li.begin(), li.end(), '0')<1 || count(li.begin(), li.end(), '1')<1) cout<<-1<<endl;
else cout<<BFS(li, n)<<endl;
}
} 这道题跟玛雅人那道题一样,但测试用例似乎有点问题。
def BFS(Q,k,n,trash):
m = len(Q)
for j in range(m):
q = Q.pop(0)
trash.append(q)
for i in range(n-1):
if '2012' in q[:i]+q[i+1]+q[i]+q[i+2:]:
return k+1
else:
if q[:i]+q[i+1]+q[i]+q[i+2:] not in Q+trash:
Q.append(q[:i]+q[i+1]+q[i]+q[i+2:])
return BFS(Q,k+1,n,trash)
while True:
try:
n = int(input())
s = input()
trash = []
char_cnt = {'0':0,'1':0,'2':0}
for i in range(n):
char_cnt[s[i]] += 1
if char_cnt['0']<1 or char_cnt['1']<1 or char_cnt['2']<1:
print(-1)
elif '2012' in s:
print(0)
else:
print(BFS([s],0,n,trash))
except:
break
//看了好久了没看出哪里有问题,烦请各位大佬帮忙指摘下,不胜感激啊
//思路是bfs
#include<iostream>
#include<string>
#include<queue>
#include<set>
using namespace std;
struct ele{
string s;//对应的string
int cnt;//由init的string经过ct次移位得到的
ele(){}
ele(string ss, int cc):s(ss), cnt(cc){}
};
int istrue(string s){
if(s.find("2012")!=-1){
return 1;
}else{
return 0;
}
}
int main(){
string s;
int len, ct, i;
while(cin>>len){
cin>>s;
//初步判断 不含有0 1 两个2
if(s.size()<4 || s.find("0")==-1 || s.find("1")==-1 || s.find("2")==-1){
cout<<-1<<endl;
continue;
}
ct=0;
for(i=0; i<len; i++){
if(s[i]=='2')
ct++;
}
if(ct<2){
cout<<-1<<endl;
continue;
}
ct=0;//记录移位次数
queue<ele> q;
q.push(ele(s, ct));
string tp;
ele e;
int flag=0;
set<string> st;
while(!q.empty()){
e=q.front();
q.pop();
if(st.count(e.s)){//访问过的不再访问了,记录的是相同string的情况下移位次数最少的那个
continue;
}else{
st.insert(e.s);
}
if(istrue(e.s)){
cout<<e.cnt<<endl;
flag=1;
break;
}
ct++;//移位
for(i=0; i<e.s.size()-1; i++){
tp=e.s;
swap(tp[i], tp[i+1]);
q.push(ele(tp, ct));
}
}
if(flag==0){
cout<<-1<<endl;
}
}
return 0;
}
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
struct N{ //转移状态
string str;
int t; //转换次数
};
queue<N> Q;
map<string,int> M;
bool IsInMap(string s){ //s是否在map中
if(M.find(s)==M.end()){
M[s]=0; //不在则插入
return false;
}
else return true;
}
bool IsSolve(string s){
if(s.find("2012",0)!=string::npos) return true;
else return false;
}
void BFS(int n){ //n为字符串长度
while(!Q.empty()){ //Q非空
N nown=Q.front();
Q.pop();
string temp;
for(int i=0;i<n-1;i++){
temp=nown.str; //取出当前状态
swap(temp[i],temp[i+1]); //交换
if(IsInMap(temp)) continue; //交换之后在map中已经存在了
if(IsSolve(temp)){ //当前状态是目标
cout<<nown.t+1<<endl;return;
}
//其他状态,入队
N newn;
newn.str=temp;newn.t=nown.t+1;
Q.push(newn);
}
}
cout<<-1<<endl;
}
int main(){
int l;
string str;
while(cin>>l){
while(!Q.empty()) Q.pop();
M.clear();
cin>>str;
if(IsSolve(str)) cout<<0<<endl; //不用转换
else{
M[str]=0;
N f;
f.str=str;f.t=0;
Q.push(f);
BFS(l);
}
}
}
#include<iostream>
(720)#include<vector>
#include<string>
(765)#include<algorithm>
#include<queue>
(789)#include<map>
using namespace std;
struct ele //记录层数
{
string str;
int step;
};
int BFS(string s) //广度搜索
{
map<string, int> visited; //访问标记数组
queue<ele> con; //保存数据队列
ele k;
k.str = s;
k.step = 0;
con.push(k);
visited[s] = 1;
int step = -1;
while (!con.empty())
{
ele z = con.front();
con.pop();
if (z.str.find("2012") != string::npos)
{
step = z.step;
break;
}
else
{
z.step++;
for (int i = 0; i < z.str.size() - 1; i++)
{
swap(z.str[i], z.str[i + 1]);
if (visited.find(z.str) == visited.end())
{
con.push(z);
visited[z.str] = 1;
}
swap(z.str[i], z.str[i + 1]);
}
}
}
return step;
}
int main()
{
int n;
while (cin >> n)
{
string s;
cin >> s;
cout << BFS(s) << endl;
}
} #include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
static unordered_map<int, int> mp{
{122, 2},
{212, 1},
{221, 2},
{1022, 3},
{1202, 2},
{1220, 3},
{2210, 3},
{2201, 2},
{2021, 1},
{2120, 2},
{2102, 1},
{2012, 0},
};
int main()
{
int N;
string str;
while (cin >> N >> str)
{
vector<int> vec[3] = {};
for (int i = 0; i < N; i++)
vec[str[i] - '0'].push_back(i);
int ans = 1e9;
for (int i = 0; i < vec[2].size(); i++)
{
int a = vec[2][i];
for(auto b : vec[0])
for(auto c : vec[1])
for(int j = i+1; j < vec[2].size(); j++)
{
int d = vec[2][j];
vector<int> tmp{a, b, c, d};
sort(tmp.begin(), tmp.end());
int key = (str[tmp[0]] - '0') * 1000 + (str[tmp[1]] - '0') * 100
+ (str[tmp[2]] - '0') * 10 + (str[tmp[3]] - '0');
ans = min(ans, tmp[3] - tmp[1] + tmp[2] - tmp[0] - 4 + mp[key]);
}
}
cout << (ans == 1000000000 ? -1 : ans) << "\n";
}
return 0;
} #include <iostream>
#include <queue>
#include <unordered_map>
#include <string>
using namespace std;
int main(){
int n;
while(cin >> n){
string inputstr;
cin >> inputstr;
if(n<4){//字符串太短,不可能出现2012,直接退出
cout << "-1" << endl;
continue;
}
queue<string> q;
q.push(inputstr);//初始字符串入队
unordered_map<string,int> password;
password[inputstr]=0;//初始字符串入词典
while(!q.empty()){//当队列为空时退出循环
string str=q.front();
if(str.find("2012")!=string::npos){//如果找到2012则查字典
cout << password[str] << endl;
break;
}
q.pop();
for(int i=0;i<str.length()-1;i++){//没找到2012,开始交换
string mid=str;//使用副本
char c=mid[i];
mid[i]=str[i+1];
mid[i+1]=c;//交换mid[i]和mid[i+1]
if(password.find(mid)==password.end()){
q.push(mid);
password[mid]=password[str]+1;
}
}
}
//是遍历完队列导致的退出,而不是找到2012导致的退出,则输出-1
if(q.empty()==true){
cout << "-1" << endl;
}
}
} #include <any>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
bool judge(string str){//判断字符串里是否含有2012
if(str.size()<4)
return false;
for(int a=0,b=1,c=2,d=3;d<str.size();a++,b++,c++,d++){
if(string(str.begin()+a,str.begin()+d+1)=="2012"){
return true;
}
}
return false;
}
int main() {
int n;
while(cin>>n){
string str;
cin>>str;
map<string,int>my_map;//my_map["123"]=3表示"123"是第三次位移
queue<string>my_queue;
my_queue.push(str);
my_map[str]=0;
bool flag = false;//标记是否解开密码
while(!my_queue.empty()){
auto temp = my_queue.front();
my_queue.pop();
if(judge(temp)){
cout<< my_map[temp]<<endl;
flag = true;
break;
}
for(int i=0;i<temp.size()-1;i++){
string temp2 = temp;
swap(temp2[i], temp2[i+1]);
if(my_map.count(temp2)==0){
my_queue.push(temp2);
my_map[temp2] = my_map[temp]+1;
}
}
}
if(!flag)
cout<<-1<<endl;
}
} #include <iostream>
#include <queue>
#include <set>
#include <string>
using namespace std;
struct Node {
string str; //字符串
int depth; //移位次数(广度优先搜索的深度)
Node(string str, int depth): str(std::move(str)), depth(depth) {}
};
//判断字符串是否含有“2012”这几个字符
bool contain2012(string str) {
if (str.length() < 4) {
return false;
}
int count0 = 0,
count1 = 0,
count2 = 0; //统计‘0’、‘1’、‘2’字符的个数
for (const auto& ch : str) {
count0 += ch == '0';
count1 += ch == '1';
count2 += ch == '2';
}
return count0 >= 1 && count1 >= 1 && count2 >= 2;
}
//交换字符串str中下标为index和index+1的相邻字符
string swap_char(string str, int index) {
swap(str[index], str[index + 1]);
return str;
}
int main() {
int n;
string str;
while (cin >> n >> str) {
if (!contain2012(str)) { //无解
cout << -1 << endl;
continue;
}
if (str.find("2012") != string::npos) { //无需移位
cout << 0 << endl;
continue;
}
queue<Node>myQueue; //用于广度优先搜索的队列
set<string>visited; //标记已访问的字符串
myQueue.push({str, 0});
visited.insert(str);
while (!myQueue.empty()) {
Node current = myQueue.front();
myQueue.pop();
string str = current.str;
int depth = current.depth + 1;
for (int i = 0; i < n - 1; i++) {
string str1 = swap_char(str, i);
if (str1.find("2012") != string::npos) {
cout << depth << endl;
goto exit; //作用相当于多重循环的break
}
if (visited.find(str1) == visited.end()) {
myQueue.push({str1, depth});
visited.insert(str1);
}
}
}
exit: //终止多重循环的出口
;
}
return 0;
} #include<iostream>
#include<cstdio>
#include<string>
#include<queue>
#include<map>
using namespace std;
struct code {
string name;
int num;
code(string na,int n):name(na),num(n){}
};
int BFS(string str)
{
map<string, bool> string_num;
queue<code> q;
q.push(code(str, 0));
string_num[str] = true;
while (!q.empty())
{
code current = q.front();
q.pop();
if (current.name.find("2012")!=string::npos)
{
return current.num;
}
for (int i = 0;i < current.name.size() - 1;i++)
{
{
string next=current.name;
swap(next[i], next[i + 1]);
if (string_num.find(next) != string_num.end() && string_num[next]);
else
{
q.push(code(next, current.num + 1));
string_num[next] = true;
}
}
}
}
return -1;
}
int main()
{
string str;
int n;
while (cin >> n >> str)
{
printf("%d\n", BFS(str));
}
return 0;
} #include <algorithm>
#include <climits>
#include <cstdio>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>
#include <map>
using namespace std;
struct info{
string s;
int n;
info(string s1,int n1){
s=s1;n=n1;
}
};
//unordered要比order快,因为只需要做个标记,不需要排序
unordered_map<string,int> mymap;
queue<info> myqueue;
int bfs(string s){
mymap.clear();
myqueue.push(info(s,0));
mymap[s]++;
int result=INT_MAX;
while (!myqueue.empty()) {
info temp=myqueue.front();
myqueue.pop();
int pos=temp.s.find("2012");
if(pos!=string::npos){
result=min(result,temp.n);
}else{
for(int i=0;i<temp.s.size()-1;i++){
string temp2=temp.s;
swap(temp2[i],temp2[i+1]);
//temp.n+1<result这个判断最重要,如果当前的步数已经比result要高,就没必要继续遍历下去了
if(mymap[temp2]==0&&temp.n+1<result){
myqueue.push({temp2,temp.n+1});
mymap[temp2]++;
}
}
}
}
if(result==INT_MAX){
result=-1;
}
return result;
}
int main() {
int n;
while (scanf("%d",&n)!=-1) {
string s;
cin>>s;
cout<<bfs(s)<<endl;
}
} #include <bits/stdc++.h>
using namespace std;
const int N=15;
int n;
string s;
bool st[N];
int minstep=1e9;
//dfs做***超时,对使用未超时的测试用例均正确
void dfs(int u, int step)
{
if(u>n-1) return ;
if(s.find("2012")!=-1)
{
minstep=min(minstep, step);
return;
}
for(int i=0;i<s.size()-1;i++)
{
if(!st[i])
{
st[i]=true;
swap(s[i],s[i+1]);
dfs(u+1,step+1);
swap(s[i],s[i+1]);
st[i]=false;
}
}
}
int main()
{
while(cin>>n>>s){
memset(st, 0, sizeof st);
minstep=1e9;
dfs(0,0);
if(minstep==1e9)
cout<<-1<<endl;
else
cout<<minstep<<endl;
}
return 0;
} #include <iostream>
#include<queue>
#include<map>
using namespace std;
typedef struct Node{
string str;//当前字符串
int step;//第几次移位
}Node;
int bfs(string str){//广度优先
queue<Node> q;//广度优先队列
map<string,bool> visited;//该某字符是否被搜索过
Node node;
node.str=str;
node.step=0;//第一个字符串移位次数为0
q.push(node);
int step=-1;//解不开密码的默认返回
while(!q.empty()){//队列非空
Node temp=q.front();//队头元素
q.pop();
string s=temp.str;//当前检查的字符串
visited[s]=true;//令该字符串在map中有记录
if(s.find("2012")==s.npos){//若当前字符串不包含2012
for(int i=0;i<s.size()-1;i++){//进行n-1次交换
swap(s[i],s[i+1]);//移位
if(visited.find(s)==visited.end()&&visited[s]!=true){//移位后的字符串没有被访问过,要么没有加入map,要么不为true
Node x;
x.str=s;
x.step=temp.step+1;//次数加1
q.push(x);//入队
}
swap(s[i],s[i+1]);//还原
}
}else{
step=temp.step;//找到目标字符串
break;//注意找到后要终止循环
}
}
return step;
}
int main()
{
int n;
while(cin>>n){
string str;
cin>>str;
cout<<bfs(str)<<endl;//广度优先遍历
}
return 0;
}
from collections import deque from copy import deepcopy def switcher(s,level): ss = [] for i in s: ss.append(i) result = [] for i in range(len(ss)-1): new_one = deepcopy(ss) new_one[i+1] = ss[i] new_one[i] = ss[i+1] new_s = ''.join(new_one) result.append( (new_s,level+1) ) return result while True: try: m = input() orig_s = input().strip() if '2012' in orig_s: print(0) continue q = deque([]) used = set() q.extend(switcher(orig_s,0)) used.add(orig_s) #print(orig_s) while len(q) != 0: #print(q) one,level = q.popleft() if one in used: continue else: if '2012' in one: print(level) break else: q.extend(switcher(one,level)) used.add(one) else: print(-1) except: break
#include <cstdio>
#include <set>
#include <queue>
#include <string>
#include <map>
using namespace std;
set<string> already;
queue< pair<string, int> > q;
const string target("2012");
int n;
string exchangee(const string& s, int pos)
{
string ret(s);
auto t = ret[pos];
ret[pos] = ret[pos-1];
ret[pos-1] = t;
return ret;
}
void init()
{
already.clear();
while(!q.empty()) q.pop();
}
void BFS(const string& s0)
{
q.push(make_pair(s0, 0));
already.insert(s0);
while(!q.empty())
{
auto now = q.front(); q.pop();
string nows = now.first;
if(nows.find(target) != nows.npos)
{
printf("%d\n", now.second,nows.c_str());
return;
}
for(auto i = nows.size()-1; i > 0; --i)
{
auto te = exchangee(nows, i);
{
if(already.insert(te).second)
{
q.push(make_pair(te, now.second+1));
}
}
}
}
printf("-1\n");
}
int main()
{
while(scanf("%d", &n) != EOF)
{
if(n==0) break;
init();
string si;
si.clear();
getchar();
for(int i = 0; i<n;++i)
{
char temp;
scanf("%c", &temp);
si.push_back(temp);
}
getchar();
BFS(si);
}
} #include<bits/stdc++.h>
using namespace std;
struct node{
string s;
int t;
bool operator<(const node &rs)const{//步数少的在优先队列前面。
return t>rs.t;
}
};
string str;
int bfs(){
priority_queue<node>q;
map<string,int>mp;
mp[str] = 1;
q.push({str,0});
while(!q.empty()){
node now = q.top();q.pop();
if(now.s.find("2012")!=string::npos){
return now.t;
}
for(int i = 0;i<now.s.size()-1;i++){
swap(now.s[i],now.s[i+1]);
if(mp.count(now.s)){
swap(now.s[i],now.s[i+1]);
continue;
}
mp[now.s] = 1;
q.push({now.s,now.t+1});
swap(now.s[i],now.s[i+1]);
}
}
return -1;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
cin>>str;
printf("%d\n",bfs());
}
} import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ //移位 int n=sc.nextInt(); String code=sc.next(); int moveTime=getMoveTime(code); System.out.println(moveTime); } } private static int getMoveTime(String code) { if(code.length()<4)return -1; List<String>record=new ArrayList<>();//记录已经交换过的结果,剪枝。 Queue<Help>queue=new LinkedList<>(); Help help=new Help(code,0); queue.offer(help); record.add(code); while(!queue.isEmpty()) { help=queue.poll(); if(help.s.contains("2012")) return help.cnt; for(int i=0;i<code.length()-1;i++) { char[]arr=help.s.toCharArray(); char temp = arr[i]; arr[i] = arr[i+1]; arr[i+1] = temp; String after=new String(arr); if(!record.contains(after)) { record.add(after); queue.offer(new Help(after,help.cnt+1)); } } } return -1; } } class Help{ String s; int cnt; Help(String s,int cnt){ this.s=s; this.cnt=cnt;//交换次数 }
#include <iostream>
(720)#include <vector>
#include <map>
(747)#include <algorithm>
#include <iterator>
(2102)#include <cmath>
#include <set>
(855)#include <cstdio>
#include <cstdlib>
(895)#include <stack>
#include <queue>
(789)#define PI acos(-1)
using namespace std;
typedef struct Node{
string state="";//状态
//int id;//标识
int t=0;//移动次数
}Node;
int fun(string str){
//根据输入的str,以三进制的形式输出其对应的数值
int id=0;
int l=str.length();
int i;
int x;
for(i=0;i<l;i++){
x=str[i]-'0';
id+=x*pow(3,l-i-1);
}
return id;
}
int BFS(string str){
//采用广度优先搜索得到结果
int l=str.length();//获取字符串长度
if(str.find("2012")<l)return 0;
int sizes=pow(3,l);//标技数组的长度
int i;
bool mark[sizes];
for(i=0;i<sizes;i++){
mark[i]=false;//该状态未被使用
}
queue<Node>q;//状态队列
Node first;
first.t=0;
first.state=str;
int id=fun(str);
mark[id]=true;
q.push(first);
while(!q.empty()){
//队列不为空
Node now=q.front();//出队列
q.pop();//出队列
//cout<<now.state<<"出队列"<<endl;
//状态扩展,任意交换相邻的两个字符
for(i=0;i<l-1;i++){
string nextstate=now.state;
char ctmp=nextstate[i];
nextstate[i]=nextstate[i+1];
nextstate[i+1]=ctmp;//交换
int nextt=now.t+1;
int isexit=nextstate.find("2012");
if(isexit!=-1){
//目标状态
return nextt;
}
int nextid=fun(nextstate);//计算状态值
if(mark[nextid])continue;//说明该状态已经遍历过
Node next;//构造新状态
next.state=nextstate;
next.t=nextt;
q.push(next);
//cout<<nextstate<<"入栈"<<endl;
mark[nextid]=true;
}
}
//直到队列为空都没能找到目标状态,则说明不存在
return -1;
}
int main(){
int n;
string str;
while(cin>>n){
cin>>str;
int ans=-1;
int i;
int znum=0;
int onum=0;
int tnum=0;
for(i=0;i<str.length();i++){
if(str[i]=='0'){
znum++;
}else if(str[i]=='1'){
onum++;
}else if(str[i]=='2'){
tnum++;
}
}
if(onum>=1&&znum>=1&&tnum>=2){
//先做一个简单的排除,如果字符串中含有的0,1,2不能满足2012,直接排除
ans=BFS(str);
}else{
}
cout<<ans<<endl;
}
return 0;
} #include <iostream>
#include <queue>
#include <string>
#include <unordered_set>
using namespace std;
/*
思路:BFS
*/
//当前str一次变化后字符串vec
vector<string> nextChangeStrVec(string str) {
vector<string> results;
for (int i = 1; i < str.size(); i++) {
swap(str[i], str[i - 1]);
results.push_back(str);
swap(str[i], str[i - 1]);
}
return results;
}
int main() {
int n;
while (cin >> n) {
string str;
cin >> str;
queue<string> que;
unordered_set<string> set; //标记str是否已经处理过
que.push(str);
set.insert(str);
int change = 0;
int flag = 0; //是否找到第一个2012
while (!que.empty()) {
if (flag)
break;
int size = que.size(); //由于size动态变化,先取出值
++change; //每层结果+1
//分层
for (int i = 0; i < size; i++) {
string front = que.front();
que.pop();
if (front.find("2012") != -1) {
flag = 1;
}
vector<string> nexts = nextChangeStrVec(front);
for (auto str: nexts) {
if (set.find(str) != set.end())
continue;
que.push(str);
set.insert(str);
}
}
}
if (flag)
cout << change - 1 << endl;
else
cout << -1 << endl;
}
}