「杂题乱刷2」CF109D
1.「算法笔记」构造选讲2.「杂题乱刷」CF1221B3.「杂题乱刷」CF468A4.「杂题乱刷」AT_abc337_e5.「杂题乱刷」洛谷 P88666.「杂题乱刷」CF1937C & CF1936A7.「杂题乱刷」CF1934D28.「杂题乱刷」at_abc092_d & AT_arc093_b9.「杂题乱刷」CF74E10.「杂题乱刷」AT_abc096_d11.「杂题乱刷」CF1973D12.「杂题乱刷」CF1977B13.「杂题乱刷」P827914.「杂题乱刷」P1067815.「杂题乱刷2」CF1015D Walking Between Houses16.「杂题乱刷2」CF1889A Qingshan Loves Strings 217.「杂题乱刷2」CF1567D18.「杂题乱刷2」CF1493C19.「杂题乱刷2」CF862C20.「杂题乱刷2」CF1365G21.「杂题乱刷2」AT_arc184_a22.「杂题乱刷2」CF1370F223.「杂题乱刷2」CF2040D24.「杂题乱刷2」CF1738F Connectivity Addicts
25.「杂题乱刷2」CF109D
题目链接
CF109D Lucky Sorting 2000 (1800)
解题思路
我们考虑现将原序列离散化成排列,此时约束条件严格强于原题目,然后只找一个可以交换的数字,此时约束条件依然强于原题目。
那么此时我们考虑如何操作,设可以操作的数字为
-
如果此时数字
所在的位置为 ,那么此时不需要交换。 -
如果此时数字
所在的位置不为 ,且数字 所在的位置为 ,那么此时交换 两个数字的位置。 -
如果此时数字
所在的位置不为 ,且数字 所在的位置不为 ,设位置 此时的数字为 ,那么此时先交换 两个数字的位置。那么此时交换 两个数字的位置。
操作次数严格不大于
参考代码
ll n,id;
ll a[1000010];
ll b[1000010];
map<ll,ll>mp,mp2;
ll pos[1000010];
bool f(ll x)
{
ll pd=1;
while(x)
pd&=x%10==4 || x%10==7,
x/=10;
return pd;
}
vector<pii>ans;
void swp(ll x,ll y)
{
if(x==y)
return ;
swap(a[x],a[y]);
swap(pos[a[x]],pos[a[y]]);
ans.pb({x,y});
}
void _clear(){}
void solve()
{
_clear();
cin>>n;
forl(i,1,n)
cin>>a[i],
f(a[i])?id=i:id=id;
forr(i,n,1)
b[i]=a[i];
sort(b+1,b+1+n);
ll pd=1;
forl(i,1,n)
pd&=a[i]==b[i];
if(pd)
{
cout<<0<<endl;
return ;
}
ll k=1;
forl(i,1,n)
mp[a[i]]++;
for(auto i:mp)
mp2[i.x]=k,
k+=i.y;
forl(i,1,n)
a[i]=mp2[a[i]]++;
if(id==0)
{
cout<<-1<<endl;
return ;
}
// forl(i,1,n)
// cout<<a[i]<<' ';
// cout<<endl;
forl(i,1,n)
pos[a[i]]=i;
id=a[id];
forl(i,1,n)
{
if(pos[i]==i)
continue;
if(pos[id]==i)
swp(i,pos[i]);
else
swp(pos[id],i),
swp(i,pos[i]);
}
cout<<ans.size()<<endl;
for(auto i:ans)
cout<<i.x<<' '<<i.y<<endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效