DIV3カップは本当に、暴力もDIV2より暴力的であること(これは明らかに事を示していない)ので、私にとっては、これは、このような振り向くと長い時間を無駄にしませんでした自分自身の問題として、非常に面倒腱で、その後、私が目を覚まします来て。そして、これは実際にもに分かれて......
質問:爆発FOUND
問題B:文字列、簡単な貪欲
質問C:文字列、簡単な数学
Dタイトル:DP
A.三人の友
テストあたりの時間制限
1秒
テストごとのメモリ制限
256メガバイト
入力
標準入力
出力
標準出力
三つの友人はお互いを満たすために予定されています。最初に、位置における第一の友人ステー\(X = \) 、位置に第2の友人ステー\(X = B \)と位置での第3友人ステー\(X = C \)には座標軸\(オックス\) 。
1分でそれぞれ独立友他の友人からは、によって位置xxを変更することができます(1 \)\左かによって、(1 \)\右側(すなわちセットに\(X:= X-1 \)または\(X := X + 1 \))、あるいは、それを変更しないでください。
友人の各ペア間の距離の総和-さんが総ペアワイズ距離をご紹介しましょう。A'A '、B'B'とc'cは「それに対応し、第一、第二と第三の友人の最終位置とします。次いで、総ペアワイズ距離である(| A'-B '| + | A'-C' | + | B'-C '| \)\、\(| X |が\)の絶対値である\(X \) 。
友人は、それらが最適に移動する場合、彼らは達することができる最小の総ペアワイズ距離に興味を持っています。それぞれの友人が何度も移動しません。だから、より正式に、彼らは1分後に到達することができ、最小の総ペアワイズ距離を知りたいです。
あなたは答えなければならない\(Q \)独立したテストケースを。
入力
入力の最初の行は、一つの整数含ま\(Q \) (\(1≤q≤1000\)テストケースの数を- )。
次\(Q \)行はテストケースを記述する。\(I \)番目のテストケースは三つの整数として与えられる\(B \)と\(C \) (\(1≤a、B、c≤10^ 9 \)の初期位置- )第一、第二、第三の友人に対応。友人の位置が等しくすることができます。
出力
友人が最適の位置を変更した場合の最小合計ペアワイズ距離(友人の各対間の距離の最小和) -各テストケースのためにそれに答えを印刷します。それぞれの友人が何度も移動しません。だから、より正式に、あなたは彼らが、1分後に到達することができ、最小の総ペアワイズ距離を見つける必要があります。
例
入力
コピー
8
3 3 4
10 20 30
5 5 5
2 4 3
1 1000000000 1000000000
1 1000000000 999999999
3 2 5
3 2 6
出力
コピー
0
36
0
0
1999999994
1999999994
2
4
//https://codeforces.com/contest/1272/problem/A
/*
题意:
a,b,c 三点位置都可以走一格或者不走
求走后 |a′−b′|+|a′−c′|+|b′−c′| 的值最小
所以三重遍历就可以搜索完了全部情况
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int T;
long long a, b, c;
int main()
{
scanf("%d", &T);
while(T--){
scanf("%I64d %I64d %I64d", &a, &b, &c);
long long A, B, C;
long long ans = 0x3f3f3f3f3f3f3f3f; // 把 ans 放一个很大的数
// 三重遍历
for(long long i = -1; i < 2; i++){
for(long long j = -1; j < 2; j++){
for(long long k = -1; k < 2; k++){
A = a; B = b; C = c;
A += i; B += j; C += k;
ans = min(ans, llabs(A - B) + llabs(A - C) + llabs(B - C));
}
}
}
printf("%I64d\n", ans);
}
return 0;
}
B.雪歩行ロボット
テストあたりの時間制限
2秒
テストごとのメモリ制限
256メガバイト
入力
標準入力
出力
標準出力
最近、あなたは雪の歩行ロボットを購入しているし、それを家に持って来ました。あなたの家はセルであると仮定((0,0)\)\無限のグリッド上。
また、このロボットの一連の命令を持っています。これは、文字列として書かれている\(S \)文字'L'、R ''、 'U'と'D'からなります。ロボットがセル内にある場合((X、Y)\)\今、彼は、隣接するセル(現在の命令に応じて)のいずれかに移動することができます。
- 現在の命令が「L」である場合、ロボットは左に移動することができる\((X-1、Y)\) 。
- 現在の命令が「R」である場合、ロボットは右に移動することができる((X + 1、Y)\)\。
- 現在の命令が「U」である場合、ロボットの上部に移動することができる((X、Y + 1)\)\。
- 現在の命令が「D」である場合、ロボットの下に移動することができる\((X、Y-1)\) 。
ロボットの訪問、いくつかのセルの場合(:あなたは、マニュアルの最後のページに警告気づい除く )\((0,0)\それが壊れる二回続い)。
セル内のロボットが始まる場合は有効である一連の命令はそう\((0,0)\) 、与えられた指示を行い、訪問以外のセル((0,0)\)\ 2回以上と終了セル内のパス\((0,0)\) 。また、セル\((0,0)\)訪問する必要があり、最大で 2回:最初と最後に(パスが空であれば、それは一度だけ訪れています)。たとえば、次の命令シーケンスが有効と考えられている:「UD」、「RL」、「UUURULLDDDDLDDRRUU」、および以下は無効とみなされます。「U」(エンドポイントではありません((0,0)\)\と) "UUDD"(セル\((0,1)\)二回訪れています)。
命令の初期シーケンスは、しかし、有効ではないかもしれません。あなたは、以下の方法でそれを再プログラムすることを決めたので、あなたのロボットは壊したくはありません:あなたは、命令の初期シーケンスから(おそらくすべてまたはnone)命令をいくつかを削除するあなたが望むよう残りの指示を再配置し、オンになりますあなたのロボットが移動します。
あなたの仕事はできるだけ初期シーケンスからいくつかの命令として削除し、シーケンスが有効であるように、残りのものを再配置することです。あなたが得ることができる最大の長さの有効なシーケンスを報告します。
あなたが選ぶことができることに注意してください任意の(あなたはスワップの数またはメトリックの任意の他の類似を最小限にする必要はありません)、残りの命令の順序を。
あなたは答えなければならない\(Q \)独立したテストケースを。
入力
入力の最初の行は、一つの整数含ま\(Q \) (\(^ 41≤q≤2⋅10\)テストケースの数を- )。
次の\(Q \)行はテストケースが含まれています。\(I \)番目のテストケースは、文字列SS少なくともなるように与えられていない\(1 \)とせいぜい\(10 ^ 5 \)文字'L'、R ''、 'U'と' D」 -命令の初期シーケンス。
これは、の合計ことが保証されている(| | S \)\(どこ)\ \(| | S SSの長さである)(すべてのテストケースの上に105105を超えていない)≤10^ 5 \ |(\Σを|よ)。
出力
各テストケースのためにそれに答えを印刷します。最初の行に残っている命令の最大数を印刷します。2行目の残りの命令の有効なシーケンスを出力ロボットが実行しなければならないTT。移動は、印刷されたシーケンスの順に左から右に行われます。いくつかの答えがある場合は、いずれかを印刷することができます。答えがある場合(0 \)\、あなたは空の行を印刷するように許可されている(しかし、あなたはそれを印刷しないことができます)。
例
入力
コピー
6
LRU
DURLDRUDRULRDURDDL
LRUDDLRUDRUL
LLLLRRRR
URDUR
LLL
出力
コピー
2
LR
14
RUURDDDDLLLUUR
12
ULDDDRRRUULL
2
LR
2
UD
0
注意
「LR」と「RL」:最初のテストケースでは2つだけ可能な答えがあります。
第二のテストケースに対応する画像:
トラバースの方向は問題でないことに注意してください
第3のテストケースへのもう一つの正解:「URDDLLLUURDR」。
// https://codeforces.com/contest/1272/problem/B
/*
题意:
有一串操作指令:上下左右
要求用这些操作指令从(0,0)出发然后走完后就回到(0,0)
在走的过程中不能走回头路(即不能走到相同位置上,(0,0)除外)
且要走的路要最长
那简单,用合理的指令走最大的环就行
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int T;
char ch[100005];
int u, d, l, r; // 记录原本的上下左右键
int main()
{
scanf("%d", &T);
while(T--){
u = d = r = l = 0;
scanf("%s", ch);
int len = strlen(ch);
for(int i = 0; i < len; i++){
if(ch[i] == 'U') u++;
else if(ch[i] == 'D') d++;
else if(ch[i] == 'R') r++;
else l++;
}
// printf("u:%d d:%d l:%d r:%d\n", u, d, l, r);
if(u == 0 || d == 0){ // 不能往上或往下走
if(r == 0 || l == 0) printf("0\n");
else {
printf("2\nLR\n");
}
}
else if(l == 0 || r == 0){ // 不能往左走或往右走
if(u == 0 || d == 0) printf("0\n");
else {
printf("2\nUD\n");
}
}
else {
int y = min(d, u);
int x = min(l, r);
printf("%d\n", (x + y) * 2); // 画个环
for(int i = 0; i < y; i++) printf("U");
for(int i = 0; i < x; i++) printf("L");
for(int i = 0; i < y; i++) printf("D");
for(int i = 0; i < x; i++) printf("R");
printf("\n");
}
}
return 0;
}
C.もう一つの壊れたキーボード
テストあたりの時間制限
2秒
テストごとのメモリ制限
256メガバイト
入力
標準入力
出力
標準出力
最近、ノルウェーでは、文字列見つかった\(S = s_1s_2 ... S_N \)からなる(\ n)を\ラテン文字を小文字。彼のタイピング速度を向上させるための練習として、彼は文字列のすべての部分文字列を入力することにしました(\ S)\。はい、すべての\(\ FRAC {N(N + 1)} {2} \)それらの!
サブストリング(複数可\)\非空の文字列である\(X = S [... B] = s_as_ {+ 1} ... S_B \) (\(1≤a≤b≤n\) )。たとえば、「オート」と「トン」「オートマトン」の部分文字列です。
まもなく運動開始後、ノルゲはつまり、彼は使用することができ、彼のキーボードが壊れていたことに気づいた\(K \)ラテン文字\(C_1、C_2、...、c_kを\)のうち(26 \)\。
その後、ノルゲは、文字列のどのように多くの部分文字列に興味を持つようになった\(S \) 、彼はまだ彼の壊れたキーボードを使って入力することができます。この番号を見つけるために彼を助けます。
入力
最初の行は、二つのスペースで区切られた整数を含む\(N \)と\(K \) (\(1≤n≤2⋅10^ 5 \) 、\(1≤k≤26\) )-の長さを文字列\(S \)と、キーボード上のまだ利用できるラテン文字の数。
2行目は文字列が含まれ\(S \)正確で構成されるを\(N \)ラテン文字を小文字。
3行目は(株)スペースで区切られた個別の小文字のラテン文字が含まれ\(C1、C2を、...、CK \) -キーボード上の文字がまだ使用可能。
出力
のみ利用可能文字を使用して入力することができ、SSのサブストリングの数-単一番号を印刷\(C1、C2、...、CKを\) 。
例
入力
コピー
7 2
abacaba
a b
出力
コピー
12
入力
コピー
10 3
sadfaasdda
f a d
出力
コピー
21
入力
コピー
7 1
aaaaaaa
b
出力
コピー
0
注意
最初の例でノルゲは、サブストリングを印刷することができ\(S [1 ... 2] \) 、\(S [2 ... 3] \)、$ S [1 ... 3] $、\(S [1 ... 1] \) 、\(S [2 ... 2] \) 、\(S [3 ... 3] \) 、\(S [5 ... 6] \) 、\(S [6 ... 7] \) 、\(S [5 ... 7] \) 、\(S [5 ... 5] \) 、\(S [6 ... 6] \) 、\(S [7 ... 7] \) 。
// https://codeforces.com/contest/1272/problem/C
#include<iostream>
#include<cstdio>
using namespace std;
/*
题意:
有一串字符串
你的键盘可以输入 k 个字符
问用这个 k 个字符可以写多少个字符串满足远字符串的子序列
样例一:
7 2
abacaba
a b
用 a b 可以组成 12 种
分析:
原字符粗前面的 "aba" 就可以分为 6 种 后面的 "aba" 就可以组成 6 种
分析一下,当可写的字符串长度为 n 时,满足 n * (n - 1) * (n - 2) * ... * 2 * 1 = n * (n + 1) / 2
然后把这每一段的 (n) 加一起就可以(注意越界)
*/
int n, k;
char s[200005];
char ch[30];
int main()
{
cin >> n >> k;
cin >> s;
for(int i = 0; i < k; i++) cin >> ch[i];
long long ans = 0;
long long len = 0;
bool flag;
for(int i = 0; i < n; i++){
// printf("i:%d s:%c\n", i, s[i]);
flag = false;
for(int j = 0; j < k; j++){
// printf("j:%d s:%c ch:%c\n", j, s[i], ch[j]);
if(s[i] == ch[j]){
flag = true;
len++;
break;
}
}
// printf("i:%d len:%d flag:%d\n", i, len, flag);
// printf("\n");
if(!flag || i == n - 1){
ans += (len + 1) * len / 2;
len = 0;
}
}
printf("%I64d\n", ans);
return 0;
}
D.削除一つの要素
テストあたりの時間制限
2秒
テストごとのメモリ制限
256メガバイト
入力
標準入力
出力
標準出力
あなたはnnは整数からなる配列AAを与えられています。
あなたは削除することができ、ほとんど1つので、この配列から要素。従って、配列の最終的な長さは\(N-1 \)または\(N \) 。
あなたの仕事は、可能な最大の長さを計算することで厳密に増加残りの配列の連続した部分配列を。
RRへLLからインデックスを有する隣接サブアレイAAがあることを思い出してください([L ... R] = a_l \)\、\(A_ {L + 1}、...、A_R \) 。サブアレイ\([L ... rは] \)増加厳密に呼び出された場合\(a_l <A_ {L + 1} <⋯<A_R \) 。
入力
入力の最初の行は1つの整数が含ま\(N \) (\(2≤n≤2⋅10^ 5 \) )-中の要素の数(\)\。
入力の2行目に含まれる\(N \)整数\(A_1、A_2、...、A_N \) (\(1≤ai≤10^ 9 \) )、ここで\(a_iを\)である\(I \ )番目の要素\(\) 。
出力
ひとつの整数を印刷する-の最大長厳密に増加アレイAAの連続する部分配列を多くても1つの要素で除去した後。
例
入力
コピー
5
1 2 5 3 4
出力
コピー
4
入力
コピー
2
1 2
出力
コピー
2
入力
コピー
7
6 5 4 3 2 4 3
出力
コピー
2
注意
最初の例では、削除することができます(A_3 = 5 \)\。次いで、得られた配列は、[1,2,3,4]、[1,2,3,4]に等しくなり、その最大の増加部分配列の長さに等しくなる(4 \)\。
// https://codeforces.com/contest/1272/problem/D
#include<iostream>
#include<cstdio>
using namespace std;
/*
题意:
可以剔除一个数或者不剔除
求操作或者不操作后最长的升序子序列长度
*/
// dp[][0] 表示没有剔除时当前位置的最长上升子序列
// dp[][1] 表示剔除一个数之后当前位置的的最长上升子序列
int dp[200005][2];
int n, num[200005];
int ans;
//10
//1 2 5 4 3 8 9 4 8 10
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &num[i]);
dp[i][0] = 1; // 每一位最短长度是 1
}
for(int i = 2; i <= n; i++){
if(num[i] > num[i - 1]) {
dp[i][0] = dp[i - 1][0] + 1;
dp[i][1] = dp[i - 1][1] + 1; // 因为第 1 位剔除了,所以从 0 开始
}
if(num[i] > num[i - 2]){
dp[i][1] = max(dp[i][1], dp[i - 2][0] + 1); // 每次与 dp[i - 2][0] 相比,符合只剔除一个数的规则
}
ans = max(ans, max(dp[i][1], dp[i][0])); // 每次比较当前位以得到最长上升子序列长度
}
// for(int i = 1; i <= n; i++){
// printf("i:%d zero:%d one:%d\n", i, dp[i][0], dp[i][1]);
// }
printf("%d\n", ans);
return 0;
}
ああ、対象は多くのことをブログに長い時間をダウンコピーするには、次の時間を複製することはできません。
レコードのスパイシーなチキンの成長: