微软夏令营笔试测验第一题 Array Partition

来源:互联网 发布:简述单片机的引脚功能 编辑:程序博客网 时间:2024/06/14 12:43

时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
Given an integer array A1, A2 … AN, you are asked to split the array into three continuous parts: A1, A2 … Ap | Ap+1, Ap+2, … Aq | Aq+1, Aq+2, … AN.

Let S1, S2 and S3 denote the sums of each part:

S1 = A1 + A2 + … + Ap

S2 = Ap+1 + Ap+2 + … + Aq

S3 = Aq+1 + Aq+2 + … + AN

A partition is acceptable if and only if the differences between S1, S2 and S3 (i.e. |S1 - S2|, |S2 - S3|, |S3 - S1|) are no more than 1.

Can you tell how many different partitions are acceptable?

输入
The first line contains an integer N.

The second line contains N integers, A1, A2 … AN.

For 30% of the data, N ≤ 100

For 70% of the data, N ≤ 1000

For 100% of the data, N ≤ 100000, -1000000 ≤ Ai ≤ 1000000

输出
The number of acceptable partitions.

样例解释
The three acceptable partitions are:

3 | 2 | 1 0 2

3 | 2 1 | 0 2

3 | 2 1 0 | 2

样例输入
5
3 2 1 0 2
样例输出
3

动态规划问题,按照题目的要求只有可能出现三种情况,x,x,x;x,x,x+1;x,x,x-1;很明显这三种情况是互斥的。
对于每一种情况有O(n)的算法,首先从后向前计算,用一个数组保存当前位置及之后的位置包含多少个和为sum的情况,用一个数组进行统计,之后采用从前到后遍历,遍历确定前半段的和等于固定值之后寻找跳过一个的位置存储的值(保证最少有一个划分元素),相加即可

#include <iostream>#include <vector>#include <stdio.h>#include <algorithm>#include <map>#include <string>#include <limits.h>#include <cmath>#include <iomanip>#include <sstream>#include <unordered_set>#include <unordered_map>#include <deque>#include <stdio.h>  using namespace std;int *s, *x, n, c;int res = 0;vector<int>  cal_pos_sum(int *s,int n,int z){    if (n <= 0)        return vector < int > {};    vector<int> res(n, 0);      if (s[n-1]==z)        res[n - 1] = 1;    int temp = s[n - 1];    for (int i = n-2; i >= 0; --i)    {        temp += s[i];        if (temp == z)            res[i] = res[i + 1] + 1;        else            res[i] = res[i + 1];    }    return res;}int count_sum(int x,int y){    vector<int> pos_sum;    pos_sum = cal_pos_sum(s,n,y);    int res = 0;    int sum = 0;    for (int i = 0; i < n - 2; ++i)    {        sum += s[i];        if (sum == x){            res += pos_sum[i + 2];            }        }    return res;}int main(){    int all_sum = 0;    int i;    scanf_s("%d", &n);    s = new int[n];    for (i = 0; i<n; i++){        scanf_s("%d", &s[i]);        all_sum += s[i];    }    if ((all_sum + 1) % 3 == 0)    {        int out = 0;        c = (all_sum + 1) / 3;        out = count_sum(c,c - 1) + count_sum(c,c) + count_sum(c - 1,c);        cout << out << endl;    }    else if ((all_sum - 1) % 3 == 0)    {        int out = 0;        c = (all_sum - 1) / 3;        out = count_sum(c,c + 1) + count_sum(c,c) + count_sum(c + 1,c);        cout << out << endl;    }    else if ((all_sum) % 3 == 0)    {        int out = 0;        c = (all_sum) / 3;        out = count_sum(c,c);        cout << out << endl;    }    else        cout << 0 << endl;    return 0;}
阅读全文
0 0
原创粉丝点击