缓慢补题中。
思路:
选取最左1,最右0,记录位置为l,r。需要记录一下0的个数,记为n0。
1. l和其他所有1换位置,r和其他所有0换位置。(n=16,答案长度+14)
这一步是保证,要求出错的串,这么换后没有改变。其他要求正确的串,l一定能被换成0,r一定能被换成1。(如果不能,那一定是和要求出错的串一模一样了,显然不可能)。
2. 除了l和r,其他位子都两两换。(n=16,答案长度+91(14*13/2),累计105)
到这一步,如果一个串和要求出错的串0和1 个数分布相同,则已经被排好序了。第三步要处理01个数不相同的。
3. 想要处理成0…001011…1。的形式。也就让 lr这个10组合在中间会师。
一开始,就是想粗暴仿照步骤2,内部排序。1~n0内部两两交换,n0+1~n内部两两交换。
自己测都对,就是WA!!仔细读题,你给出的答案个数长度不能超过120……所以换思路。还有15步可以用。
怎么换?肯定是
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
/*测试程序
vector<string>te;
int n;
void dfs(string s,int level)
{
if(level==n)
{
te.push_back(s);
return;
}
dfs(s+'0',level+1);
dfs(s+'1',level+1);
}
int ok=1;
void init()
{
te.clear();
string s="0";
dfs(s,0);
}
bool check(string s)
{
int tg=0;
for(auto i:s)
{
if(i=='1')
{
tg=1;
}
if(tg&&i=='0')
{
return false;
}
}
return true;
}
*/
void solve()
{
string s;
cin>>n>>s;
s.insert(s.begin(),'0');
int l=0;//最左1
int r=0;//最右0
int n0=0,n1=0;
for(int i=1;i<=n;i++)
{
if(s[i]=='1')
{
if(!l)
{
l=i;
}
n1++;
}
else
{
r=i;
n0++;
}
}
vector<pii> ans;
for(int i=1;i<=n;i++)
{
if(s[i]=='0')
{
if(i!=r)
{
ans.push_back(pii(i,r));
}
}
else
{
if(i!=l)
{
ans.push_back(pii(l,i));
}
}
}
for(int i=1;i<n;i++)
{
if(i==l||i==r)
{
continue;
}
for(int j=i+1;j<=n;j++)
{
if(j==r||j==l)
{
continue;
}
ans.push_back(pii(i,j));
}
}
for(int i=1;i<l;i++)
{
ans.push_back(pii(i,l));
}
for(int i=n0;i>l;i--)
{
ans.push_back(pii(l,i));
}
for(int i=n0+1;i<r;i++)
{
ans.push_back(pii(i,r));
}
for(int i=n;i>r;i--)
{
ans.push_back(pii(r,i));
}
cout<<ans.size()<<endl;
for(auto it:ans)
{
int x= min(it.first,it.second);
int y= max(it.first,it.second);
cout<<x<<" "<<y<<endl;
}
// cout<<"test"<<endl;
// init();
// int err=0;
// for(auto s:te)
// {
//
// cout<<s.substr(1,n)<<"->";
//
// for(auto[x,y]:ans)
// {
// if(s[x]>s[y])
// {
// s[x]='0';
// s[y]='1';
// }
// }
// string ss=s.substr(1,n);
// bool res=check(ss);
// cout<<ss<<" "<<res<<endl;
// if(!res)
// {
// err++;
// }
// }
// cout<<"err"<<err<<endl;
// if(err!=1)
// {
// ok=0;
// }
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
//
// if(ok)
// {
// cout<<"ok"<<endl;;
// }
// else
// {
// cout<<"no"<<endl;
// }
return 0;
}
基于l和r。我卡这里很长时间,,具体见代码。我代码另附一些测试程序。