• zoj Candies 思维


    http://acm.zju.edu.cn/changsha/showProblem.do?problemId=31

    题意:

    给你n个非负整数,然后输入n个x[i],x[i] == -1表示第i个数不知道是多少,x[i] != -1表示第i个数是x[i], 然后我们在给出每个数和他左右邻居的和,起点终点只有两个数的和a[i],

    输入下标x求x[i]可能取得的最大值,如果x[i]已经知道就输出x[i];

    思路:

    首先我们分析可以知道x[2],x[5],x[8]  ..... 都是已经知道的(下标从零开始), 其次我们只要知道其中的除了x[2],x[5]..这种情况的数的其他任意一个我们都能够求出整个序列,所以如果存在n%3 == 0 || n%3 == 1的情况我们肯定能够利用a[n - 1] = x[n - 1] + x[n - 2]来求出所有序列。 那么未知的就是n%3 == 2的情况了,只要知道其中一个值(除了x[2]..那种情况),我们就能求出所有的序列。如果未知,那么该序列肯定是x[0] = -1, x[1] = -1, x[2] = 已知 ... x[3] = -1, x[4] = -1, x[5] = 已知...的情况,然后模型就可以转化成给你一个序列,知道任意相邻两个序列的和,求该序列中某个值得最大取值。 当然枚举其中一个就能解决问题时间复杂度O(n*m),在本题中不能满足,那么我们就可以假设一个区最小,一个取最大,然后找出取最大值的位置中的最小,这是我们可以移动给另一个所能移动的最多的。然后周处取最小值的里面的最小值,这是我们移动时可以移动的最小的,然后求最值就好了。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    
    #define lc l,m,rt<<1
    #define rc m + 1,r,rt<<1|1
    #define pi acos(-1.0)
    #define ll long long
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d
    ", x)
    #define keyTree (chd[chd[root][1]][0])
    #define Read()  freopen("din.txt", "r", stdin)
    #define Write() freopen("dout.txt", "w", stdout);
    
    
    #define M 100007
    #define N 100007
    
    using namespace std;
    
    int dx[4]={-1,1,0,0};
    int dy[4]={0,0,-1,1};
    
    const int inf = 0x7f7f7f7f;
    const int mod = 1000000007;
    
    const double eps = 1e-8;
    
    int x[N],X[N],a[N],sum[N];
    int pos;
    int n;
    
    int main()
    {
        int n;
        while (scanf("%d",&n)!=EOF)
        {
            CL(x,0);
            pos = -1;
            for (int i = 0; i < n; ++i)
            {
                scanf("%d",&x[i]); X[i] = x[i];
                if (i % 3 != 2 && x[i] != -1)  pos = i;
            }
            for (int i = 0; i < n; ++i) scanf("%d",&a[i]);
    
            x[2] = a[1] - a[0]; X[2] = x[2];
            for (int i = 5; i < n; i += 3)
            {
                x[i] = a[i - 1] - a[i - 2] + x[i - 3];
                X[i] = x[i];
            }
    
            //012 345
            if (n % 3 == 0)
            {
                x[n - 2] = a[n - 1] - x[n - 1];
                for (int i = n - 3; i >= 0; --i)
                {
                    x[i] = a[i + 1] - (x[i + 1] + x[i + 2]);
                }
            } else if (n % 3 == 1) { // 012 345 6
                x[n - 1] = a[n - 1] - x[n - 2];
                for (int i = n - 3; i >= 0; --i)
                {
                    x[i] = a[i + 1] - (x[i + 1] + x[i + 2]);
                }
            } else if (n % 3 == 2) { // 012 345 67
                if (pos != -1)
                {
                    if (pos % 3 == 0)
                    {
                        x[pos + 1] = a[pos + 1] - (x[pos] + x[pos + 2]);
                        for (int i = pos + 3; i < n; ++i)
                        {
                            x[i] = a[i - 1] - (x[i - 1] + x[i - 2]);
                        }
                        for (int i = pos - 2; i >= 0; --i)
                        {
                            x[i] = a[i + 1] - (x[i + 1] + x[i + 2]);
                        }
                    } else if (pos % 3 == 1) {
                        x[pos - 1] = a[pos] - (x[pos + 1] + x[pos]);
                        for (int i = pos + 2; i < n; ++i)
                        {
                            x[i] = a[i - 1] - (x[i - 1] + x[i - 2]);
                        }
                        for (int i = pos - 2; i >= 0; --i)
                        {
                            x[i] = a[i + 1] - (x[i + 1] + x[i + 2]);
                        }
                    }
                }
            }
    
            int f = 0;
            for (int i = 0; i < n; ++i)
            {
                if (x[i] == -1)
                {
                    f = 1; break;
                }
            }
            int Mi = 0, Ma = inf;
            if (f == 1)
            {
                int cnt = 0;
                for (int i = 0; i < n; ++i)
                {
                    if (i%3 == 0)
                    {
                        sum[cnt++] = a[i + 1] - x[i + 2];
                        if (i + 2 < n) sum[cnt++] = a[i + 2] - x[i + 2];
                    }
                }
                x[0] = 0; cnt = 0;
                int tmp = 0;
                for (int i = 1; i < n; ++i)
                {
                    if (i%3 != 2)
                    {
                        x[i] = sum[cnt++] - tmp;
                        if (i % 3 == 1)  Ma = min(Ma, x[i]);
                        else Mi = max(Mi, -x[i]);
                        tmp = x[i];
                    }
                }
                int m,p;
                scanf("%d",&m);
                while (m--)
                {
                    scanf("%d",&p);
    
                    if (X[p] != -1) printf("%d
    ",X[p]);
                    else
                    {
                        if (p % 3 == 0)  printf("%d
    ",x[p] + Ma);
                        else printf("%d
    ",x[p] - Mi);
                    }
                }
            } else {
                int m,p;
                scanf("%d",&m);
                while (m--)
                {
                    scanf("%d",&p);
                    printf("%d
    ",x[p]);
                }
            }
    
    
    
    
        }
        return 0;
    }
    

      

  • 相关阅读:
    《C程序设计语言现代方法》第5章 选择语句
    《C语言程序设计现代方法》第4章 编程题
    《C语言程序设计现代方法》第4章 表达式
    《算法竞赛入门经典》第1章 程序设计入门
    《C语言程序设计现代方法》第3章 格式化输入/输出
    《C语言程序设计现代方法》第2章 编程题
    《C语言程序设计现代方法》第2章 C语言基本概念
    《C语言程序设计现代方法》第1章 C语言概述
    Linux和Windows下的进程管理总结
    silvetlight ListBox Item项自动填满
  • 原文地址:https://www.cnblogs.com/E-star/p/3346914.html
Copyright © 2020-2023  润新知