[洛谷写题-C ++] P3131-サブシーケンスの合計が7人制ラグビー

問題

難易度:人気-

説明:

https://www.luogu.com.cn/problem/P3131

配列を入力し、合計が7で割り切れる最長の部分文字列を見つけます。

入力範囲:

入力長:1≤N≤50,000

入力番号のサイズ:0…1,000,000

ケースを入力してください:

7
3
5
1
6
2
14
10

私のコード:

数学の質問を比較すると、それが直接暴力的である場合、n!時間計算量は、レベルごとにsum [i] = sum [i-1] + N、次に%7であっても、最長の時間計算量は次のようになります。 n ^ 2、それでも機能しない場合は、数学の問題になります。

2つの合計の解を考えると、7で割り切れる区間合計の長さを比較できます。

区間Mには、NとX、ΣM=ΣN+ΣX、および

ΣM%7 = 1、ΣN%7 = 1

ΣM%7-ΣN%7 = 0

(ΣM-ΣN)%7 = 0

ΣX%7 = 0 ——————>大きな区間Mから、区間Nが見つかった場合は、2を減算して、7で割り切れる区間Xを取得します。Nが可能な限り小さい場合は、 Xは7で割り切れる最長の区間であり、Xを取得するには、最初にNを取得します。つまり、Mの終了位置とNの開始位置を取得します。(ΣM%7 =ΣN%7、ここで両方の残りは7になります)

C ++の場合

#include <iostream>
using namespace std;

int num, temp, res = 0, be[8], en[8], sum[50001];

int main() {
	cin >> num;
	for (int i = num; i-- > 0;) { // 从尾到头获取逐个区间的和并求余(自动形成了所有同结尾的最大区间)
		cin >> temp;
		sum[i] = (temp + sum[i + 1]) % 7;
	}
	for (int i = num; i-- > 0;) // 然后得出相应的开始结束位置
		if (en[sum[i]]) be[sum[i]] = i; else en[sum[i]] = i;

	for (int i = 7; i-- > 0;) // 通过开始结束为止得出最大的区间
		if(be[i] && en[i]) res = max(res, en[i] - be[i]);

	cout << res;
}

 

 

 

おすすめ

転載: blog.csdn.net/qq_28033719/article/details/110553039