Educational Codeforces Round 92(Rated for Div.2)A,B,C題解

22503 ワード

1389A. LCM Problem
題意:範囲[l,r]を与える.この範囲内で2つの整数x,y,l<=LCM(x,y)<=rを見つける.
考え方:x,yは等しくないから.では、この範囲内の最小lcmはlの2倍であるべきです.l*2<=rだけです.それでいい
#include
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--) {
		long long l, r;
		cin >> l >> r;
		if (l *2 > r) {
			cout << -1 << ' ' << -1 << endl;
		}
		else {
			cout << l << ' ' << l *2 << endl;
		}
	}
	return 0;
}

1389B. Array Walk
标题:配列をあげて、n個の数があります.初期位置は下の1と表記されたa 1で、配列上でk回移動することができます.ある位置に移動すると、対応する点数が得られます.しかし、2つの制限があります.2回連続して左に移動することはできず、左に移動する回数はz回を超えてはならない.最后に最高何点を得ることができるかを闻きます.
構想:2−nの位置を列挙し,左右1−z回移動する.得点が一番高い場合を選択します.具体的には、コードのコメントを参照してください.
#include
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--) {
		int n, k, z;
		cin >> n >> k >> z;
		vector<long long> v(n);
		for (auto& val : v) {
			cin >> val;
		}
		int i, j;
		int idx = 0;
		long long ans = 0;
		bool can = false;
		vector<long long> sum(n);
		sum[0] = v[0];
		for (i = 1; i < n; i++) {
			sum[i] = sum[i - 1] + v[i];
		}
		ans = sum[k];
		for (i = 1; i < n; i++) {
			for (j = 1; j <= z && j <= k - i; j++) {
                // sum     
                // k-i      i     ,        
                //               j 。 i->i-1 ,i-1>i              
				if (j * 2 <= k - i)
                    // sum[i + k - 2 * j - i]  i        k-2*j-i         
                    // i      j         。  i + k - 2 * j - i               
					ans = max(ans, (v[i] + v[i - 1]) * j + sum[i + k - 2 * j - i]);
                //         j 。           ,    i    。
				else if (j * 2 - 1 <= k - i)
					ans = max(ans, (v[i] + v[i - 1]) * (j - 1) + v[i - 1] + sum[i]);
			}
		}
		cout << ans << endl;
	}
	return 0;
}

1389C. Good String
題意:文字列にはループシフトと右ループシフトの2つの操作があります.例えば、文字列「123456」は、左ループ位置を行った場合「234561」、右ループシフトを行った場合「612345」である.文字列を良いと呼び、左サイクルシフトと右サイクルシフトを行った場合にのみ等しい.文字列に0~9しか含まれていない文字列が指定され、文字列の一部の文字を削除できます.文字列のエッジを良くするには、最低数の文字列を削除する必要があります.
構想:左右のループが1ビットシフトした後の文字列が完全に等しいことを満たすには、文字列はすべて1つの文字列から構成されるか、例えば、「111111」、またはサンプルの「2525252525」のような2つの文字ループしか現れない.文字列を構築して判断することができます文字が1文字しかない場合は、1文字あたりの出現回数を記録すればよい.2文字ループが現れる場合は、残りの2文字を列挙し、元の文字列と一致させることができます.複雑度は10*10*nです.
#include
using namespace std;
 
int match(string str, char ch1,char ch2) {
	int flag = 0;
	int i;
	int cnt = 0;
	for (i = 0; i < str.size(); i++) {
		if (flag == 0) {
			if (str[i] == ch1) {
				flag = 1;
				cnt++;
			}
 
		}
		else {
			if (str[i] == ch2) {
				flag = 0;
				cnt++;
			}
		}
	}
	return cnt%2==0?cnt:0;
}
 
int main() {
	ios::sync_with_stdio(false);
	int t;
	cin >> t;
	while (t--) {
		string str;
		cin >> str;
		unordered_map<char, int> mmid;
		int i, j;
		for (i = 0; i < str.size();i++) {
			mmid[str[i]]++;
		}
		int ans = str.size();
		int len = str.size();
		for (auto& [a, b] : mmid) {
			ans = min(ans, len - b);
		}
 
		for (i = 0; i < 10; i++) {
			for (j = 0; j < 10; j++) {
				if (j == i)continue;
				int tmp = len - match(str, i + '0', j + '0');
				ans = min(ans, tmp);
			}
		}
		cout << ans << endl;
	}
 
 
	return 0;
}