Codeforces Round #650 (Div. 3) D : Task On The Board

https://codeforces.ml/contest/1367/problem/D

在比赛的时候我想的是直接dfs爆搜,T了...其实这题是一个构造题,对于b数组中的每一个数b[i] ,只有t串中比t[i] 大的位置才会对b[i] 有贡献,我们首先知道了对于j位置有b[j] = 0 时,那么t[j] 里放的字符肯定是最大的,知道了最大的字符的下标,我们就可以得到第二大字符的下标(只要某些下标k与最大的下标绝对差之和等于b[k],那么它就满足条件),然后我们就可以得到第三大字符的下标(只要某些下标k与最大的下标和第二大的下标的绝对差之和等于b[k],那么它就满足条件).....知道了哪些是最大,哪些是第二大..就可以根据字符串s来造字符串t了。

这题其实更多的是关心下标之间的关系,对每个字符是什么其实不太关心(字符只提供个大小关系),我在做的时候思维就一直局限在每个字符是什么了,唉,模板题做多了思维太差劲了

#include <iostream>
#include <cstdio>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
int T,m,isok,t;
string str;
map<char,int> M;
vector<int> b,store;//store存大字符的下标 
vector<char> ans;
int Abs(int x){
	if(x > 0) return x;
	return -x; 
}
void solve()
{
	cin>>str;
	M.clear();store.clear();isok = 0;
	for(int i = 0; i < str.size(); i++) M[str[i]]++;
	cin>>m;
	vector<int> flag(m);
	for(int i = 0; i < m; i++) flag[i] = 0;
	b.resize(m,0);
	for(int i = 0; i < m; i++){
		cin>>b[i];
	}
	for(int i = 0; i < m; i++){
		if(b[i] == 0){
		flag[i] = 1;
		isok++;
		store.push_back(i);
		}
	} 
	t = 1;
	while(isok < m){
		t++;
		for(int i = 0; i < m; i++){
			if(flag[i]){
//				cout<<flag[i]<<" ";
//				cout<<"tioaguo"<<i<<endl;
				continue;
			}
			int cur = 0;
			for(int k = 0; k < store.size(); k++) cur += Abs(i-store[k]);
			if(cur == b[i]){
				flag[i] = t;
				isok++;
			}
			//cout<<isok<<" "<<store.size()<<" "<<i<<endl;
		}
		
		for(int i = 0; i < m; i++)
			if(flag[i] == t) store.push_back(i); 
	}
	ans.resize(m);
	char word = 'z';
	for(int i = 1; i <= t; i++){
		int num = 0;
		for(int k = 0; k < m; k++)
			if(flag[k] == i) num++;
		while(word >= 'a' && M[word] < num){
			word--;
		}
		for(int p = 0; p < m; p++){
			if(flag[p] == i) ans[p] = word;
		}
		word--;
	}
	for(int i = 0; i < m; i++) cout<<ans[i];
	cout<<endl;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>T;
	for(int i = 1; i <= T; i++) solve();
	return 0;
}

总结:1.写代码的时候要养成好习惯,变量用到的时候再去申请,不要把一坨变量都当成全局变量,这样的话debug的时候很烦,而且有多组输入的时候还可能忘记清空

2.vector的resize(m),是把拓展出来的那部分给默认赋为0,而不是全部的都给变为0

"没有天赋异禀,那就加倍努力"
原文地址:https://www.cnblogs.com/Beic233/p/13155368.html