Description
长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样。 今天小明早上起来后发现身体虽然变小,头脑依旧不变变傻。
他有一条纸带,上面有n个数字,第i个数字为Ai。 他想把纸带选三个位置p1, p2, p3(p1 < p2 < p3)把纸带剪成4个每条长度至少为1的4条纸带。 分别为[1, p1-1], [p1+1, p2-1], [p2+1, p3-1], [p3+1, n],使得4个部分中数字之和相等。
Input
多组输入 每组测试数据第一行输入一个n(7 ≤ n ≤ 105) 第二行n个数,第i个数为Ai(0 ≤ Ai ≤ 109),表示第i个数
Output
输出字典序最小的p1,p2,p3 如果不存在这种操作,输出-1
Sample Input
7 6 2 6 2 6 2 6 7 1 2 3 4 5 6 7
Sample Output
2 4 6 -1
Hint
思路:使用尺取,详细看代码
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; #define MAXN 100010 #define INF 0x3fffffff int a[MAXN],sum[MAXN]; int p1, p2, p3; int slove(int n) { p1 = 2; p2 = 4; p3 = 6;//p1,p2,p3代表四个区间的中间位置 for (; p1 <= n; p1++)//不断更新p1的位置 { p2 = max(p2, p1 + 2); while (p2 <= n&&sum[p1 - 1] > sum[p2 - 1] - sum[p1])//如果第二个区间的值小于第一个区间的值 p2++; if (p2 >= n|| sum[p1 - 1] < sum[p2 - 1] - sum[p1])//如果第二个区间的值大于第一个区间的值就跳过 continue; p3 = max(p3, p2 + 2); while (p3 <= n&&sum[p1 - 1]>sum[p3 - 1] - sum[p2]) p3++;//判断第三个区间的值与第一个区间的值的大小关系 if (p3 >= n || sum[p3 - 1] - sum[p2]>sum[p1 - 1]) continue; if (sum[n] - sum[p3] == sum[p1 - 1])//判断第四个区间 { cout << p1 << ' ' << p2 << ' ' << p3 << endl; return 1; } } return 0; } int main() { int n; while (cin>>n) { for (int i = 1; i <= n; i++) { cin >> a[i]; sum[i] = sum[i - 1] + a[i]; } if (!slove(n)) cout << "-1" << endl; } } /********************************************************************** Problem: 1956 User: leo6033 Language: C++ Result: AC Time:788 ms Memory:2804 kb **********************************************************************/