题目地址:https://codeforces.com/gym/101606
这道题可以看成是CSL的魔法这道题的进阶
题意
给出初始序列。问如何将升序排列后初始序列又恢复到初始序列。
输出每次交换的位置,(A,B)且满足s[A-1]≥s[B-1],即第A个和第B个交换
解题思路
先将这些字符离散化,s[i].id记录每个字母的输入顺序,将输入的字符串sort后升序排列
依次遍历升序后的序列,当s[i].id!=i时说明字母在初始字符串被sort的时候位置改变了
方法1:
每次只交换两个字母,不交换字母对应的id,依照着CSL的魔法这道题中的环往下找下标,每次都与起始位置的字母交换
方法2:
每次交换两个字母和两个字母对应的id,下一次要交换的位置 :起始位置对应的id(新的id值)和起始位置
直接手动算一个例子吧:abdac
按照这两种方法输出的结果应该是
4 2
5 2
2 3
输出的结果可以不用和样例一样,毕竟方法有多种!
注意一定要满足输出的条件!!s[A-1]≥s[B-1]
ac代码
方法1:只交换字母不交换id
#include <iostream>
#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <sstream>
#define maxn 1005
typedef long long ll;
using namespace std;
int vis[maxn]={0};
struct node{
char ch;
int id;
friend bool operator <(node a,node b)
{
return a.ch<b.ch;
}
}s[maxn];
int main()
{
//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
char s1[maxn];
cin>>s1;
int len=strlen(s1);
for(int i=0;i<len;i++)
{
s[i].ch=s1[i];
s[i].id=i;
}
sort(s,s+len);
for(int i=0;i<len;i++)
{
if(s[i].id==i||vis[i]) continue;
int start=i,next=s[start].id;
while(next!=start)
{
vis[next]=1;
if(s[start].ch>=s[next].ch)
printf("%d %d\n",start+1,next+1);
else
printf("%d %d\n",next+1,start+1);
swap(s[start].ch,s[next].ch);
next=s[next].id;
}
}
return 0;
}
方法2:交换字母和id
#include <iostream>
#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <sstream>
#define maxn 1005
typedef long long ll;
using namespace std;
int vis[maxn]={0};
struct node{
char ch;
int id;
friend bool operator <(node a,node b)
{
return a.ch<b.ch;
}
}s[maxn];
int main()
{
//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
char s1[maxn];
cin>>s1;
int len=strlen(s1);
for(int i=0;i<len;i++)
{
s[i].ch=s1[i];
s[i].id=i;
}
sort(s,s+len);
for(int i=0;i<len;i++)
{
if(s[i].id==i||vis[i]) continue;
while(s[i].id!=i)
{
int now=i,next=s[now].id;
vis[now]=1;vis[next]=1;
if(s[now].ch>=s[next].ch)
printf("%d %d\n",now+1,next+1);
else if(s[next].ch>=s[now].ch)
printf("%d %d\n",next+1,now+1);
swap(s[now],s[next]);
}
}
return 0;
}