静下心来想一想——NOIP2002均分纸牌+近短时间情况总结

14 篇文章 1 订阅
2016-10-04
距离NOIP还有38天

最近一段时间,模拟考总是状态不佳。该拿的分拿不到,有不会做的题目也懒得想,暴力又懒得打,可以AC的程序又打WA了。是时候应该总结一下了。
1.懒。典型的情况就是懒得打暴力,懒得思考问题。总是觉得反正暴力打了最后还不是要更正的,于是就不打暴力了;也总是觉得反正思考问题了也很难做出正解,考完了也是还要听讲题的,不如不做。于是乎,很多题目都是在暴力中可以找到思路的问题,但是因为懒,与之失以交臂。
2.态度不端正。总是觉得反正自己是个才学的辣鸡,水平又低,做不出题目很正常,于是就一次又一次的放松对自己的要求,考试的时候就吊儿郎当的,日积月累,欠下的债不止一点。还有,觉得NOIP距离我还远,第一次听说的时候还有5、6个月去了,每天都觉得日子还久,现在可以不用急。仍然是日积月累,落下的差距越来越大。也正是因为态度不端正,对每一次的模拟考认识不清,没有重视。
3.对自己的认识不明确。有时过分看高自己,有时又过于贬低自己。喜欢在别人面前表现自己,喜欢炫耀,殊不知炫耀什么的毫无意义,遇到有难度的题目还不是束手就擒。其实的也不应该束手就擒,而是应该努力想着去解决问题,而不是一看到有难度的题目就想着自己的资历浅,做不出很正常,然后就想着打暴力算了。想着打暴力都还好,想着想着就觉得暴力毫无意义,然后干脆连暴力都懒得打了。
4.没有顽强的意志和坚强的毅力。由于2016-03-05以来养成了吊儿郎当的习惯,在初中以所谓现在学校的名号自以为天下无敌,于是就渐渐消磨了斗志,消磨了在难题面前拼搏和斗争的勇气。忘记了曾经说过,即使倒下,也要成为一座山,一道岭。现在就是还没看到敌人就已经软绵绵的倒下了。
5.缺少总结和计划(或者是计划没有效果,执行不当)。每天得过且过,每次不管是好还是不好都没有总结,不知道为什么好,为什么不好,以后也就是一头乱撞。

然后附上一点东西
来自LJ

向别人学习的经验也没有时常看看,看了一遍,过了一段时间就忘记了,毫无意义。

然后说完了正事,现在说这道毫无意义的题目。

均分纸牌

题目描述

有 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

这道题其实很简单,不会做或者希望看代码的同学真心建议再多想想,静下心来想一想。
题目意思讲的很清楚,如果你执意要看思路和代码,再往下翻吧。

显然,纸牌的移动到最后情况都是确定的,也就是每一坨纸牌的数量都是一样的,即所有纸牌数量的算术平均数。

那么,接下来怎么办呢?每一堆纸牌都可以往左或者往右挪,怎么确定呢?
要是都只往一个方向移动就好了,是吧?
没错,其实答案就是这样。
别忘了,我们的第1坨和第N坨就是往一个方向移动的!

在这里,要是你有一点思路的话,就自己思考一下,到了这一步,看了后面的代码,最后你会感慨怎么这么简单的。

那么,我们就假设mid = n / 2 ;
其实我们就只要解决1~mid和mid+1~n这两段就好了。
而且,想像左边那一截所有的牌都往左移。那么左右其实就是对称的。
但是为什么左边那一截里不会出现往右移动的呢?
往右移动不就是往左移动负数张牌吗?
讲完了,代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn = 110 ;
int h[maxn] ;
int main () {
    int i, j, k, m, n, a = 0 ;
    scanf ( "%d" , &n ) ;
    for ( i = 1 ; i <= n ; i ++ ) {
        scanf ( "%d" , h + i ) ;
        a += h[i] ;
    }
    int mid = n >> 1 , ans = 0 ;
    a /= n ;
    for ( i = 1 ; i <= mid ; i ++ ) {
        int need = a - h[i] ;
        h[i] += need ;
        h[ i + 1 ] -= need ;
        if ( need ) ans ++ ; //注意不需要移动的情况
    }
    for ( i = n ; i > mid ; i -- ) {
        int need = a - h[i] ;
        h[i] += need ;
        h[ i - 1 ] -= need ;
        if ( need ) ans ++ ;
    }
    if ( h[mid] != h[mid+1] ) ++ ans ; //中间是否需要移动
    cout << ans << endl ;
    return 0 ;
}

静下心来想一想。现在走的每一步都是走在未来成功的路上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值