CF1526 D. Kill Anton

题意:

给你一个由’A’,‘N’.‘T’,'O’四个字符组成的字符串b,现在要求你改变b的顺序得到a,使得a通过移动回到b的步数最多。
每次移动只能移动相邻两项

题解:

官方题解说:最佳情况为相同字符靠在一起
证明我也不清楚。。
证明可以看看这篇文章
按照官方题解的说法,将相同的字符排列在一起,一共就四种字符,那么也就是排列方式一共就24种(4!),我们直接暴力求出每种情况,然后求出其要移动的步数,取最大值
这个移动的步数咋求?
假设原先字符串是ANTON,下标依次是1,2,3,4,5,现在我们将其打乱成ATONN,原先的下标就成了1,3,4,2,5,那13425变回12345的步骤不就是其逆序对吗?所以对于每一种情况我们求其逆序对,然后保留最大值

这题挺好~

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[50];//记录字符个数
vector<int>id[50],c;//记录字符
string s;ll nxt;
void msort(int l,int r){//归并排序 if(l>=r)return;//区间元素小于1 int mid=l+r>>1;msort(l,mid);//分 msort(mid+1,r);//分 int i=l,j=mid+1,k=0;int t[r-l+1];while(i<=mid&&j<=r){if(c[i]<=c[j])t[k++]=c[i++]; else{//此时存在逆序对,在归并过程中记录逆序对的个数 t[k++]=c[j++];nxt+=mid-i+1;//记录逆序对数 }}while(i<=mid)t[k++]=c[i++];while(j<=r)t[k++]=c[j++];for(i=l,k=0;i<=r;i++,k++)c[i]=t[k];//将t排好序的数复制到c中
}
int main()
{ios_base::sync_with_stdio(false);int t;cin>>t;while(t--){int r[5]={0,'A','N','O','T'};//通过函数枚举各种可能性; memset(a,0,sizeof(a));//清空 id['A'-'A'].clear();id['N'-'A'].clear();id['O'-'A'].clear();id['T'-'A'].clear();cin>>s;for(int i=0;i<s.size();i++){a[s[i]-'A']++;//记录每个字母的个数 id[s[i]-'A'].push_back(i+1); }ll ans=0;string as;do{c.clear();nxt=0;//清零记录下一种情况的操作数for(int i=1;i<=4;i++){//四个字符分别连续存入形成一个新的字符串 c.insert(c.end(),id[r[i]-'A'].begin(),id[r[i]-'A'].end());}/*cout<<"c= ";for(int i=0;i<c.size();i++)cout<<s[c[i]-1];cout<<endl; */msort(0,c.size()-1);if(nxt>ans){ans=nxt;as="";for(int i=1;i<=4;i++) as+=string(a[r[i]-'A'],(char)r[i]);//存入此时的最优字符串,即前面c的原串 }}while(next_permutation(r+1,r+5));//对四个字符全排列的各种可能性; if(ans!=0)cout<<as<<endl;else cout<<s<<endl;//ans为0说明原字符串已经为最优解 } return 0;
}

我还有看到一种写法,本质一样,它将转化后的字符串下标定为1,2,3,4…,根据这个将原字符串下标定义为nxt[j],然后跑逆序对,一样的

for(int i=0;i<len;i++){//将该情况的字符串转为数字 for(int j=0;j<=3;j++){if(mp[s[i]]==nxt[j]){//每次打乱nxt c[i]=j;break;}}}
#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\n",a,b);
typedef long long ll;
using namespace std;
//qdu打铁匠
inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w;
}
const int maxn=2e5+9;
int nxt[]={0,1,2,3};
ll a[maxn];
ll c[maxn],b[maxn];
map<char,int>mp;
ll cnt=0;
void unite(int l,int mid,int r){if(l>=r)return ;unite(l,(l+mid)>>1,mid);unite(mid+1,(mid+1+r)>>1,r);int i=l,j=mid+1;for(ll k=l;k<=r;++k){if(j>r||i<=mid&&c[i]<=c[j]) b[k]=c[i++];else b[k]=c[j++],cnt+=mid-i+1;}for(ll k=l;k<=r;++k) c[k]=b[k];
}
string s;
ll cal(int len){for(int i=0;i<len;i++){//将该情况的字符串转为数字 for(int j=0;j<=3;j++){if(mp[s[i]]==nxt[j]){//每次打乱nxt c[i]=j;break;}}}cnt=0;unite(0,(len-1)>>1,len-1);//求逆序对 return cnt;
}
void solve(){cin>>s;string a,n,o,t;for(int i=0;i<s.length();i++){if(s[i]=='A')a+='A';if(s[i]=='N')n+='N'; if(s[i]=='O')o+='O';if(s[i]=='T')t+='T';}string ans=s;ll sum=0;do{ll now=cal(s.size());if(now>sum){//得到更大的逆序对,即需要步数更多 sum=now;ans.clear();for(int i=0;i<=3;i++){if(nxt[i]==0)ans+=a;if(nxt[i]==1)ans+=n;if(nxt[i]==2)ans+=t;if(nxt[i]==3)ans+=o;} }}while(next_permutation(nxt,nxt+1+3));cout<<ans<<endl;
}
int main()
{int t=read();mp['A']=0;mp['N']=1;mp['T']=2;mp['O']=3;while(t--){solve();}
}

CF1526 D. Kill Anton相关推荐

  1. CodeForces - 1526D Kill Anton(模拟)

    题目链接:https://vjudge.net/problem/CodeForces-1526D 题目大意:给出一个只有四种字母组成的字符串 AAA,要求将其重排列 BBB,使得贡献最大.贡献指的是, ...

  2. Codeforces Round #723 (Div. 2) D. Kill Anton 线段树 + 暴力

    传送门 文章目录 题意: 思路: 题意: 给你一个只有ANTOANTOANTO四个字母的字符串,你每次可以交换相邻两个,花费为111,让后让你打乱字符串,使得将打乱的字符串还原为原来的字符串的花费最小 ...

  3. Codeforces Round #723 (Div. 2)

    Codeforces Round #723 (Div. 2) 题号 题目 知识点 A Mean Inequality 签到 B I Hate 1111 思维 C Potions (Easy Versi ...

  4. [CF/AT]各大网站网赛 体验部部长第一季度工作报告

    文章目录 CodeForces #712 (Div. 1)--1503 A. Balance the Bits B. 3-Coloring C. Travelling Salesman Problem ...

  5. 【Codeforces】Codeforces之丰【部分题解】

    Codeforces之丰 [by_041] 文章目录 Codeforces之丰 [by_041] @[toc] Codeforces Round #721 (Div. 2) A. And Then T ...

  6. 【解题报告】CF DIV2 #ROUND 723 A~D

    [解题报告]CF DIV2 #ROUND 723 A~D 比赛链接 比赛评价: 发现这场十点就开了,然后就和ph巨佬一起玩了一场.我两分别再A和B罚时罚飞了,索性后面把C1,C2整出来了 排名2500 ...

  7. Linux shell 学习笔记(2)— 监测程序、磁盘空间和处理文件(ps -ef、top、kill、df、du 、grep、tar)

    1. 监测程序 1.1 检查进程 默认情况下,ps 命令只会显示运行在当前控制台下的属于当前用户的进程. $ ps PID TTY TIME CMD 3081 pts/0 00:00:00 bash ...

  8. 如何kill同一个应用的所有进程

    命令 如果你要kill nginx的所有进程只需如下命令: ps -ef | grep nginx | grep -v grep|awk '{print $2}' | xargs kill -9 命令 ...

  9. linux kill命令

    代码 elif [ "$SIGNAL" = 'reload' ]; then kill -USR1 $PID 总结:kill -9 pid 等同于kill -USR9 pid 等同 ...

最新文章

  1. 前端Vue学习之路(五)插件的使用
  2. 【错误记录】Ubuntu 中 ROOT 用户无法启动 Visual Studio Code 开发环境 ( 推荐在普通用户下使用 VSCode 开发环境 )
  3. Machine Learning - Andrew Ng on Coursera (Week 1)
  4. 《JAVA与模式》之装饰模式
  5. 萌新的Linux的学习之路(十) --ip设置管理
  6. C# :异步编程的注意点
  7. 路由器和交换机的区别,太经典了
  8. erlang连接数据库mysql_[原]Erlang连接mysql问题解决
  9. mac 接口压测工具jmeter的详细安装教程
  10. EtherCAT报文格式详解
  11. azw3怎么在Mac电脑上打开?
  12. 阿里云服务器突发性能型和共享型哪个好
  13. 浏览器 - 关于安全证书
  14. 计算机硬盘储存怎么增加,如何扩大存储空间?电脑扩大新添加的硬盘的方法
  15. 我对“Hello World”30年的爱恨情仇
  16. 学习嵌入式的你~何去何从?
  17. 函数模板和普通函数区别
  18. 重视“中心+网格化+信息化”建设,推进城市平稳发展
  19. 【转载】分贝是个什么东西?
  20. 沈阳计算机维修,联想电脑维修站查询_沈阳维修电脑_东莞维修电脑

热门文章

  1. 中国最神秘的一所大学,它只存在过8年,却成了永远的第一
  2. 一文读懂 AVL 树
  3. 件工程项目开发最全文档模板_一文带你了解微信小程序社区和小程序开发
  4. android动画送礼物,Android仿直播类app赠送礼物功能
  5. java取整公式,Java取整函数 四舍五入函数-Go语言中文社区
  6. python实例方法、类方法、静态方法的区别_Python 实例方法、类方法、静态方法的区别与作用...
  7. python 日期格式校验_python – 如何验证时间格式?
  8. python大鱼吃小鱼_python 游戏编程 大鱼吃小鱼
  9. 7-33 地下迷宫探索 (30 分)(思路加详解)
  10. 用一个单链表L实现一个栈(算法导论第十章10.2-2题)