D. Binary String Sorting(枚举位置)

Problem - 1809D - Codeforces

D. Binary String Sorting(枚举位置)_第1张图片

给定一个仅由字符0和/或1组成的二进制字符串s。

您可以对此字符串执行几个操作(可能为零)。有两种类型的操作:

选择两个相邻的元素并交换它们。为了执行此操作,您需要支付1012硬币;
选择字符串中的任何元素并删除它。为了执行此操作,您需要支付1012 + 1个硬币。

您的任务是计算将字符串s排序为非递减顺序(即将s转换为s1≤s2≤⋯≤sm,其中m是应用所有操作后字符串的长度)所需的最小硬币数量。空字符串也被认为是已按非递减顺序排序的。

输入

第一行包含一个整数t(1≤t≤104)——测试用例数。

每个测试用例的唯一行包含字符串s(1≤|s|≤3⋅105),仅由字符0和/或1组成。

所有给定字符串的长度之和不超过3⋅105。

输出

对于每个测试用例,输出一个整数——将字符串s排序为非递减顺序所需的最小硬币数量。

Example

Input

Copy

 
  

6

100

0

0101

00101101

1001101

11111

Output

Copy

1000000000001
0
1000000000000
2000000000001
2000000000002
0

在第一个例子中,您需要删除第1个元素,使字符串变为00。

在第二个例子中,字符串已经排序。

在第三个例子中,您需要交换第2和第3个元素,使字符串变为0011。

在第四个例子中,您需要交换第3和第4个元素,使字符串变为00011101,然后删除第7个元素,使字符串变为0001111。

在第五个例子中,您需要删除第1个元素,使字符串变为001101,然后删除第5个元素,使字符串变为00111。

在第六个例子中,字符串已经排序。

题解:
我们可以枚举从哪一个位置开始,左边全为0,右边全为1

如果交换的次数超过1,是不如删除的

只有这种情况才会进行交换操作10

我们利用前缀和记录0出现的次数

对于每个位置,看多少0和1要被删除

对于交换的操作,其实最多就只有一次,看看位置如果符合减1即可

 

#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
 #define int long long
typedef pair PII;
typedef unsigned long long ULL;
const int N = 4e5 + 10;
int mod = 1e9 + 7;
int cnt[N]; 
void solve()
{
	string s;
	cin >> s;
	int n = s.size();
	s = " " + s;
	for(int i = 1;i <= n;i++)
	{
		cnt[i] = cnt[i - 1] + (s[i] == '0');
	}
	int ans = 1e18;
	for(int i = 0;i <= n;i++)
	{
		int x = i - cnt[i];
		int y = cnt[n] - cnt[i];
		if(i != 0&&s[i] == '0'&&s[i - 1] == '1')
		{
			ans = min(ans,(int)(x+y)*(int)(1e12 + 1) - 1);
		}
		else
		{
			ans = min(ans,(int)(x + y)*(int)(1e12 + 1));
		}
	}
	cout << ans <<"\n";
}
signed main()
{
	ios::sync_with_stdio(0 );
	cin.tie(0);cout.tie(0);
	int t = 1;
	cin >> t;
	while(t--)
	{
		solve(); 
	}
}

你可能感兴趣的:(java,开发语言)