CF1367 D. Task On The Board(构造)

linkkkk

题意:

给出字符串 s s s,给出 m m m个数 b b b
要求从 s s s m m m个不重复的位置,使得对于每个 i ( 1 < = i < = m ) i(1<=i<=m) i(1<=i<=m),满足如果 s i < s j s_i<s_j si<sj,那么 ∑ a b s ( i − j ) = b [ i ] \sum abs(i-j)=b[i] abs(ij)=b[i]
∣ s ∣ < = 50 |s|<=50 s<=50

思路:

对于 b i = = 0 b_i==0 bi==0的位置放最大的数。
这样就可以每放一个数都更新一下 b i b_i bi
然后一直选择符合条件的最大字母就可以了
如果字母的个数大于等于 0 0 0的个数就可以将 0 0 0的位置全放那个字母
然后记得每个字母只能用一次,用完了要及时向前移动指针

1
baba
2
1 0
ans=ab

代码:

// Problem: D. Task On The Board
// Contest: Codeforces - Codeforces Round #650 (Div. 3)
// URL: https://codeforces.com/problemset/problem/1367/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;typedef unsigned long long ull;
typedef pair<ll,ll>PLL;typedef pair<int,int>PII;typedef pair<double,double>PDD;
#define I_int ll
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
#define read read()
#define rep(i, a, b) for(int i=(a);i<=(b);++i)
#define dep(i, a, b) for(int i=(a);i>=(b);--i)
ll ksm(ll a,ll b,ll p){ll res=1;while(b){if(b&1)res=res*a%p;a=a*a%p;b>>=1;}return res;}
const int maxn=4e5+7,maxm=1e6+7,mod=1e9+7;
int a[30],b[55];
char ans[55];
vector<int>v;
int main(){
	int _=read;
	while(_--){
		string s;cin>>s;
		int m=read;
		rep(i,1,m) b[i]=read,ans[i]='*';
		memset(a,0,sizeof a);
		for(int i=0;s[i];i++) a[s[i]-'a']++;
		int pos=25;
		while(1){
			v.clear();
			int zero=0,cnt=0;
			rep(i,1,m){
				if(ans[i]!='*'){
				    cnt++;continue;
				}
				if(!b[i]) v.push_back(i),zero++;
			}
			if(cnt==m) break;
			while(a[pos]<zero) pos--;
			a[pos]-=zero;
		//	cout<<zero<<" "<<pos<<endl;
			rep(i,1,m){
			    if(ans[i]!='*') continue;
				if(!b[i]) ans[i]=char(pos+'a');
				else{
					for(auto tt:v) b[i]=b[i]-abs(i-tt);
				}
			}
			pos--;
			//cout<<pos<<endl;
		}
		
		rep(i,1,m) cout<<ans[i];
		puts("");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆沙睡不醒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值