「問題解」回文配列
タイトルの説明
は、N個の整数の配列Aを与え、下付きは1からNである.各下付きiに対してA[i]=A[N-i+1]を満たす場合、配列は回文と呼ばれる. 例えば,配列A={1,2,3,2,1}が回文配列である. 配列Aが回文でない場合、隣接する2つの要素を結合する方法で回文配列を得ることができる.ただし、配列の要素数は、操作ごとに1減少します. 例えば,配列A={1,2,3}はエコー配列ではないが,A[1]とA[2]をマージすることで,{3,3}がエコー配列となる. 明らかに,どのような配列要素が与えられても,最大N−1回の操作を経て,1つの数にマージされると,配列Aは必ず回文配列である.だから、本題には必ず解がある.しかし、問題は、与えられた配列Aに対して、少なくとも何回の操作を経て、Aを返信配列にすることができるかということです.
入力フォーマット
1行目:1個の整数N、配列Aを表す要素の個数2行目:N個のスペースで区切られた整数、配列Aを表す
出力フォーマット
第1行:1個の整数、最小の操作回数を表す
サンプル
サンプル入力
サンプル出力
データ範囲とヒント
1 4 3 2->5 3 2->5 5 30%のデータ 1≦N≦10 60%のデータ 1≦N≦1000 100%のデータ 1≦N≦106 1≦A[i]≦109
ぶんせき
私が初めてやったときは逆だったので、私たちが2つのポインタl,rを設定して、両側から2つの関数を比較して作るところだった.
次の3つのケースがあります Pre(l)>Suf(r)の場合、r-- Pre(l)の場合
Pre(l)=Suf(r)の場合、l+,r-- もちろん,接頭辞と接尾辞の和を用いずに,元の配列で直接加算すればよい(場合3は加算せずに直接スキップできる)
コード#コード#
は、N個の整数の配列Aを与え、下付きは1からNである.各下付きiに対してA[i]=A[N-i+1]を満たす場合、配列は回文と呼ばれる. 例えば,配列A={1,2,3,2,1}が回文配列である. 配列Aが回文でない場合、隣接する2つの要素を結合する方法で回文配列を得ることができる.ただし、配列の要素数は、操作ごとに1減少します. 例えば,配列A={1,2,3}はエコー配列ではないが,A[1]とA[2]をマージすることで,{3,3}がエコー配列となる. 明らかに,どのような配列要素が与えられても,最大N−1回の操作を経て,1つの数にマージされると,配列Aは必ず回文配列である.だから、本題には必ず解がある.しかし、問題は、与えられた配列Aに対して、少なくとも何回の操作を経て、Aを返信配列にすることができるかということです.
入力フォーマット
1行目:1個の整数N、配列Aを表す要素の個数2行目:N個のスペースで区切られた整数、配列Aを表す
出力フォーマット
第1行:1個の整数、最小の操作回数を表す
サンプル
サンプル入力
4
1 4 3 2
サンプル出力
2
データ範囲とヒント
1 4 3 2->5 3 2->5 5 30%のデータ 1≦N≦10 60%のデータ 1≦N≦1000 100%のデータ 1≦N≦106 1≦A[i]≦109
ぶんせき
私が初めてやったときは逆だったので、私たちが2つのポインタl,rを設定して、両側から2つの関数を比較して作るところだった.
int Pre(int index) {
int sum = 0;
for (int i = 1; i <= index; i ++) sum += a[i];
return sum;
}
int Suf(int index) {
int sum = 0;
for (int i = index; i <= n; i ++) sum += a[i];
return sum;
}
次の3つのケースがあります
コード#コード#
#include
#include
using namespace std;
const int M = 1e6 + 5;
int a[M];
int ans, n;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i ++) {
scanf("%d", &a[i]);
}
for (int l = 1, r = n; l < r; ) {
if (a[l] < a[r]) {
a[++ l] += a[l - 1];
++ ans;
}
if (a[l] > a[r]) {
a[-- r] += a[r + 1];
++ ans;
}
if (a[l] == a[r]) {
a[++ l] += a[l - 1];
a[-- r] += a[r + 1];
//l ++, r --;
}
}
printf("%d", ans);
return 0;
}