本文主要是介绍#529. 【美团杯2020】114514【贪心】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接
题目给出的条件是给出一个长度不超过6e5的串,它一定是由n个“114514”组成的长度为6n的串。114514的顺序一定是按照这个顺序,但是排列可以是错综复杂的,但是保证一定有解。
一个“114514”中有两个‘4’,这是很关键的,我们可以把原式拆成11(4a)51(4b)这样的形式,4a指的是出现于前面的4,4b指的是出现于后面的4。于是我们想根据(4a)、(4b)确定这个串的组合。
如果我们确定了4a、4b,那么首先就可以确定5了,从后往前,第i个4a对应第i个4b对应第i个5,于是接下去只需要确定1的位置就可以了。
这里,我们不妨将1、4作为相互关系的两个信息来进行用以确定4是4a还是4b这样的一个功能。
这里需要满足如下的条件:
- 4a前面需要有两个1
- 4b前面(4a后面)需要有一个1
譬如说,有一个后缀,该后缀有x个1以及有y个4,那么,如果x>y了,就说明现在后面有4a了,因为两个1和一个1的关系,所以后面如果有(x - y)个4a,于是剩下(2y - x)个4b,就会使得此时1的条件是可以满足的。
于是,我们可以确定每一个后缀中的4a的最少的数量,然后同时也可以确定1的位置了。
因为从贪心的角度来看,在满足上述条件的情况下,4b的前一个1,越靠后越好,所以根据这则信息,我们找到一个4b,就将其前面的一个1给它,而在其后面的但是却没有用掉的1,作为4a的1来进行使用。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 6e5 + 7;
int one[2][maxN], five[maxN], four[2][maxN], top[5]; //'1' '4a' '5' '1' '4b'
char s[maxN];
int N, len, need_a[maxN] = {0}, suff[maxN][2] = {0};
signed main()
{int T; scanf("%d", &T);while(T--){memset(top, 0, sizeof(top));scanf("%s", s + 1);len = (int)strlen(s + 1);N = len / 6;suff[len + 1][0] = suff[len + 1][1] = 0;for(int i=len; i>=0; i--){suff[i][0] = suff[i + 1][0]; //'1'suff[i][1] = suff[i + 1][1]; //'4'if(s[i] == '1'){suff[i][0]++;}else if(s[i] == '4'){suff[i][1]++;}need_a[i] = max(0, suff[i][0] - suff[i][1]);}for(int i=0; i<=len; i++) need_a[i + 1] = max(need_a[i + 1], need_a[i] - (s[i] == '4'));int pos = len;
// for(int i=1; i<=len; i++) printf("%d%c", need_a[i], i == len ? '\n' : ' ');for(int i=len, have_a = 0; i>=1; i--){if(s[i] == '4'){if(have_a < need_a[i]){four[0][++top[1]] = i;have_a++;}else{four[1][++top[4]] = i;while(pos >= i){if(s[pos] == '1') one[0][++top[0]] = pos;pos--;}while(s[pos] != '1') pos--;one[1][++top[3]] = pos;pos--;}}else if(s[i] == '5'){five[++top[2]] = i;}}while(pos >= 1){if(s[pos] == '1') one[0][++top[0]] = pos;pos--;}for(int i=N; i>=1; i--) printf("%d %d %d %d %d %d\n", one[0][(i << 1)], one[0][(i << 1) - 1], four[0][i], five[i], one[1][i], four[1][i]);}return 0;
}
这篇关于#529. 【美团杯2020】114514【贪心】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!