Educational Codeforces Round 150 (Rated for Div. 2) C. Ranom Numbers

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=2e5+10;
typedef long long ll;
//记录每个字母的最前面的位置和最后面的位置 
int Fast[5],End[5];
string s,c;
ll res=-0x3f3f3f3f;
int t;
//字母转价值 
int ch_num(char c){
	switch(c){
		case 'A':
			return 1;
		case 'B':
			return 10;
		case 'C':
			return 100;
		case 'D':
			return 1000;
		case 'E':
			return 10000;
	}
}
//判断价值符号 
int  check(int a,int b){
	return a>=b? 1:-1;
}
//求和 
ll get_sum(string s){
	ll sum=0;
	int maxr=-1;
	for(int i=s.length()-1;i>=0;i--){
		sum+=ch_num(s[i])*check(ch_num(s[i]),maxr);
		maxr=max(maxr,ch_num(s[i]));
	}
	return sum;
}
//解题思路:对于某一个字母只有两种变换,要么变大自己提供更多的价值但是前面可能会让某些价值变负,要么变小前面某些价值变正但是自己可能会变小
//因此我们采用贪心的思想,要让字母变大的同时前面的字母变负的少,要么变小让前面的字母变正的尽可能大
//一共A~E五个字母,对于某一个字母其的位置越靠前,则该字母变大的影响对前面字母最小,越靠后对前面的影响越大,因此我们选择最前面和最后面的位置 
void solve(){
	cin>>t;
	while(t--){
		res=-0x3f3f3f3f;
		cin>>s;
		memset(Fast,0x3f,sizeof Fast);
		memset(End,-1,sizeof End);
		for(int i=0;i<s.length();i++){
			Fast[s[i]-'A']=min(Fast[s[i]-'A'],i);
			End[s[i]-'A']=max(End[s[i]-'A'],i);
		}
		res=max(res,get_sum(s));
		for(int i=0;i<5;i++){
			for(int j=0;j<5;j++){//对于每一个字母变为A~E五种情况下两种的最大值 
				if(End[i]>-1){
				c=s;
				c[End[i]]='A'+j;
				res=max(res,get_sum(c));
			}
				if(Fast[i]<0x3f3f3f3f){
				c=s;
				c[Fast[i]]='A'+j;
				res=max(res,get_sum(c));
			}
		}
		}
		cout<<res<<endl;
	}
}

int main(){
	solve();
}

 

posted @ 2023-06-17 16:00  突破铁皮  阅读(41)  评论(0编辑  收藏  举报