1. 程式人生 > 其它 >Educational Codeforces Round 103 Editorial 補題ing

Educational Codeforces Round 103 Editorial 補題ing

A

A. K-divisible Sum
題意:給兩個數字n,k,構造一個有n個數的陣列使得陣列的總和可以整除k,且要使這個陣列中的每個數儘可能的小,輸出陣列中的最大值。
分情況討論:
如果n >= k;
1.如果n能整除k,那麼n個數全為1即可
2.如果n不能整除k,那麼1和2也能構造成功
如果n < k;
那麼數的取值級為 k / n 的上取整

在整數上取整中,例子:ceil(k / n) = (k + n - 1) / n
程式碼:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std; int T, n, k; void solve() { cin >> n >> k; if(n >= k) { if(n % k == 0) cout << 1 << '\n'; else cout << 2 << '\n'; } else cout << (k + n - 1) / n << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >>
T; while(T--) solve(); return 0; }

B

B. Inflation

題目大意:
一種產品的價格變化統計資料用n個正整數的陣列表示, p 0 , p 1 , p 2 . . . p n − 1 p_0,p_1,p_2...p_{n-1} p0,p1,p2...pn1,其中 p 0 p_0 p0是產品的初始價格, p i p_i pi是第i個月的價格增長情況。使用這些價格變化要求你計算每個月的通貨膨脹係數: ( p 0 + p 1 + p 2 . . . + p i − 1 ) / p i (p_0 + p_1 + p_2 ... + p_{i - 1}) / p_i

(p0+p1+p2...+pi1)/pi。你需要保證每個月的通貨膨脹係數不超過百分之k,你需要增加 p i p_i pi的值,使之成立,問最少增加多少。
題解:
一個顯然的條件:直接增加 p 0 p_0 p0即可,因為所有的通貨膨脹係數的分母均含有 p 0 p_0 p0,因此增加 p 0 p_0 p0即可。

假設增加的值為x,那麼需要滿足該公式成立
p i / ( p 0 + p 1 + p 2 + . . . + p i − 1 + x ) < = k / 100 p_i / (p_0 + p_1 + p_2 + ... + p_{i - 1} + x) <= k / 100 pi/(p0+p1+p2+...+pi1+x)<=k/100
100 ∗ p i < = k ∗ ( p 0 + p 1 + p 2 + . . . + p i − 1 + x ) 100 * p_i <= k * (p_0 + p_1 + p_2 + ... + p_{i - 1} + x) 100pi<=k(p0+p1+p2+...+pi1+x)
100 ∗ p i − k ∗ ( p 0 + p 1 + p 2 + . . . + p i − 1 ) < = k ∗ x 100 * p_i - k * (p_0 + p_1 + p_2 + ... + p_{i - 1} ) <= k * x 100pik(p0+p1+p2+...+pi1)<=kx
最後得出
x > = c e i l ( [ 100 ∗ p i − k ∗ ( p 0 + p 1 + p 2 + . . . + p i − 1 ) ] / k ) x >= ceil([100 * p_i - k * (p_0 + p_1 + p_2 + ... + p_{i - 1} ) ] / k) x>=ceil([100pik(p0+p1+p2+...+pi1)]/k)
從頭開始遍歷,找到最大的滿足條件即可

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int T, n, k;

typedef long long ll;

const int N = 110;

ll p[N];


void solve() {
	cin >> n >> k;
	for(int i = 1; i <= n; i++) cin >> p[i];
	ll res = 0, sum = p[1];
	for(int i = 2; i <= n; i++) {
		res = max(res, (100ll * p[i] - sum * k + k - 1) / k);
		sum += p[i];
	}
	cout << res << '\n';
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  
  cin >> T;
  while(T--) solve();
  
  return 0;
} 

C

C. Longest Simple Cycle

找到最大的環。
類似於數組裡最大的子序列問題
但是在dp轉移的時候需要進行一下特判,如果當前已經形成環了,那麼不在進行轉移。

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 100010;

int n, T;
int a[N], b[N];
long long dp[N];

void solve() {
	cin >> n;
	for(int i = 1; i <= n; i++) {
		cin >> dp[i];
		dp[i]--;
		//初始dp[i]的長度為c[i]的長度
	}
	for(int i = 1; i <= n; i++) cin >> a[i];
	for(int i = 1; i <= n; i++) cin >> b[i];
	
	long long res = 0;
	
	for(int i = n; i > 1; i--) {
		int d = abs(a[i] - b[i]);
		res = max(dp[i] + d + 2, res);
		if(d) dp[i - 1] = max(dp[i] + 2 + dp[i - 1] - d, dp[i - 1]); //如果當前兩點相交,那麼就已經構成環了,不能再想前轉移
	}
	cout << res << '\n';
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  
  cin >> T;
  while(T--) solve();
  
  return 0;
} 

D

D. Journey
由於走完一條路後,所有的路的方向會變反,那麼假如說當前的座標是x
如果x可以向左走,那麼向左走的最長長度為LRLR…交替的字串的長度
如果x可以向右走,那麼向右走的最長長度為RLRL…交替的字串的長度
這兩個可以預處理出來
程式碼如下:

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 300010;

int n, T;
char str[N];
int r[N], l[N];

void solve() {
	cin >> n;
	cin >> str + 1;
	int size = strlen(str + 1);
	for(int i = 1; i <= size; ) {
		int j = i;             //j 是終點 
		while(j + 1 <= size && str[j + 1] != str[j]) 
			j++;
		for(int k = i - 1; k < j; k++) 
			if(str[k + 1] == 'R') r[k] = j - k + 1;
			else r[k] = 1;
		i = j + 1;
	}
	
	
	for(int i = size; i >= 1; ) {
		int j = i;             //j - 1是終點 
		while(j - 1 >= 1 && str[j - 1] != str[j]) 
			j--;
		for(int k = i; k >= j; k--)
			if(str[k] == 'L') l[k] = k - j + 2;
			else l[k] = 1;
		i = j - 1;
	}
	
	for(int i = 0; i <= n; i++) {
		if(!i) cout << r[i] << ' ';
		else if(i == n) cout << l[i] << ' ';
		else cout << r[i] + l[i] - 1 << ' ';
	}
	cout << '\n';
	
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  
  cin >> T;
  while(T--) solve();
  
  return 0;
}