2017年湖南多校對抗賽第12場_J_數字和
阿新 • • 發佈:2019-01-06
Title:
長者對小明施加了膜法,使得小明每天起床就像馬丁的早晨一樣。 今天小明早上起來後發現身體雖然變小,頭腦依舊不變變傻。
他有一條紙帶,上面有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
思路:
(1)剛開始是準備列舉兩個點的,就是Left,Right去尋找兩個點,找到了之後就相當於把資料劃分成兩段了,通過前後的值,查詢第三個是否存在,就可以AC掉了。(存在特殊情況,全部為0的情況,特殊判斷,再次WA了2發。)
(2)第一個思路WA了兩發之後,想到全為0的情況,答案錯誤,開始第二種思路,列舉第一個點,通過第一個點開始尋找第二個點,依次尋找第三個點,最後得到結果。(在此,將全為0的情況特殊判斷一下,第一個也過了。)
兩端列舉AC:
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; long long int temp[100005],sum[100005],k; int p1,p2,p3,t; int main() { while(scanf("%d",&t)!=EOF) { sum[0] = 0; ///儲存資料 for(int rest = 1; rest<=t; rest++){ scanf("%lld",&temp[rest]); sum[rest] = temp[rest] + sum[rest-1]; } if(sum[t] == 0){ printf("2 4 6\n"); continue; } ///求某一個點,突破 int Left = 2,Right = t-1; bool sign =false; while(true) { while(Left <= Right && sum[Left-1] != (sum[t] - sum[Right])) { if(sum[Left - 1] < sum[t] - sum[Right]){ Left++; }else{ Right--; } } if(Left > Right){ printf("-1\n"); break; } for(int rest = Left+1 ; rest < Right;rest++){ ///前面一部分的和為:1~(Left-1) if(sum[Left - 1] == (sum[rest] - sum[Left]-temp[rest]) && (sum[Right] - sum[rest] - temp[Right]) == sum[Left - 1] ){ printf("%d %d %d\n",Left,rest,Right); sign = true; break; } } if(sign) break; Left++,Right--; } } return 0; }
一端列舉AC:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
long long temp[100005],sum[100005];
map<long long ,int> flag;
int main()
{
int t,Left;
while(scanf("%d",&t)!=EOF)
{
flag.clear();
sum[0] = 0;
///儲存資料
for(int rest = 1; rest<=t; rest++){
scanf("%lld",&temp[rest]);
sum[rest] = temp[rest] + sum[rest-1];
flag[ sum[rest] ] = rest;
}
if(sum[t] == 0){
printf("%d %d %d\n",2,4,6);
continue;
}
///求某一個點,突破
for( Left=2;Left <= t-3;Left++)
{
int NowSum = sum[Left-1];
if(flag[ NowSum*2 + temp[Left] ] == 0)
continue;
int p2 = flag[ NowSum*2 + temp[Left] ] + 1;
if( flag[ sum[p2] + NowSum ] == 0)
continue;
int p3 = flag[ sum[p2] + NowSum ] + 1 ;
if( NowSum*4 + temp[p2] + temp[Left] + temp[p3] == sum[t]){
printf("%d %d %d\n",Left,p2,p3);
break;
}
}
if(Left > t-3 ) printf("-1\n");
}
return 0;
}