AcWing 1996.打乱字母(贪心,二分)

题目链接

https://www.acwing.com/problem/content/1998/

思路

遍历的数组的时候,用贪心的思想,用当前字符串最好的情况与其他字符串最坏的情况对比得出应待的最大位置,用当前字符串的最坏情况与其他字符串最好情况进行对比得出应得的最小位置。

AC代码

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n;
const int N = 50010;
string a[N], b[N], c[N];
//定义三个数组,a记录输入,b数组记录最小排序情况,c数组记录最大排序情况
int main(int argc, char* argv[])
{
	cin >> n;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i];
		b[i] = c[i] = a[i];
		sort(b[i].begin(), b[i].end(), greater<char>());
		sort(c[i].begin(), c[i].end());
	}

	sort(b + 1, b + n + 1);
	sort(c + 1, c + n + 1);
	//将两个情况的数组排序
	for(int i=1;i<=n;i++)
	{
		sort(a[i].begin(), a[i].end());
		//算出a[i]的字典序排列最大情况
		int l = 1, r = n;
		while (l<r)
		{//通过a[i]的最大情况与其他字符串的最小情况进行对比,用二分进行查找
			int mid = l + r >> 1;
			if (b[mid] >= a[i])
				r = mid;
			else
				l = mid + 1;
		}
		cout << r << ' ';
		l = 1;
		r = n;
		reverse(a[i].begin(), a[i].end());//逆序,即a[i]的最坏情况
		while (l<r)
		{//用a[i]的字典序最差情况与其他字典序最好情况进行对比
			int mid = l + r + 1 >> 1;
			if (c[mid] <= a[i])
				l = mid;
			else
				r = mid - 1;
		}
		cout << r << endl;
	}
}

心得

看题目的时候根本想不到是贪心和二分,用了自己的办法做结果WA。裂开。

上一篇:【Warrior刷题笔记】1996. 游戏中弱角色的数量 【排序+倒序遍历】 详细注释,简单易懂


下一篇:《Java白皮书1996自译》01:Java技术简介