洛谷1031

题目描述
有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。

移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。

现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。

例如 N=4,4 堆纸牌数分别为:

①9②8③17④6

移动3次可达到目的:

从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ②(9 11 10 10)-> 从 ② 取 1 张牌放到①(10 10 10 10)。

输入输出格式
输入格式:
键盘输入文件名。文件格式:

N(N 堆纸牌,1 <= N <= 100)

A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000)

输出格式:
输出至屏幕。格式为:

所有堆均达到相等时的最少移动次数。

输入输出样例
输入样例#1:
4
9 8 17 6
输出样例#1:
3

可以这样考虑,从左往右移牌,把少的牌累加一下作为s,多的牌累加一下作为t,如果到了一个位置t >= s的话,说明可以把多的牌往左移了,这种移法很容易想到是最好的方法,但是问题在于要记录一下要移到左边的哪一个位置,记这个位置为p,位置p必定是当前已到达的位置的最左边少牌的位置(要除去那些通过移动牌达到平均数牌的位置)或者是左边多牌的一个位置并且这个位置还没有完全把牌移完,移动的步数加上当前位置减去p位置即可。对于第二种情况可以作一个说明,可以这样去想,这个左边多牌的位置实际上可以移动到和当前位置区间内的一个位置,从而使得区间内少牌的变成不再少牌了,其次,如果这个位置仍然多牌,那么显然还是要继续往右移牌的,那么最好就是把它不断往右边移。

#include<iostream>
#include<cstdio>
#include<string>
#include <cstring>
#include <stack>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <cmath>
using namespace std;
#define INF 0x3f3f3f3f
#define mod 1000000007
#define ll long long
bool flag[105];
int main()
{
    int n, x[105], sum = 0;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> x[i];
        sum += x[i];
    }
    int avg = sum / n, c = 0;
    int s, t, l = -1;
    s = t = 0;
    bool f = false;
    for (int i = 0; i < n; ++i) {
        if (x[i] < avg) {
            s += avg - x[i];
            if (l == -1) {
                l = i;
            }
        }
        else if (x[i] > avg) {
            t += x[i] - avg;
            if (l == -1) {
                l = i;
            }
        }
        if (s && t >= s) {
            //cout << i << endl;
            c += i - l;
            t -= s;
            s = 0;
            if (t) {
                f = true;
            }
            else {
                f = false;
            }
            if (f) {
                l = i;
            }
            else {
                l = -1;
            }
        }
    }
    cout << c << endl;
    //system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jack_zhuiyi/article/details/79900452