某天上课讲到这样一个题:
丢失的牛
1~n,乱序排列,告诉从第二个位置到最后一个位置, 每个位置的前面的数字中比它小的数的个数,求每个位置的数字是多少
N<=8000

Format
Input
第一行给出数字N 接下来N-1,每行给出一个数字

Output
一行输出一个数字。共输出N行。

样例输入
5
1
2
1
0

样例输出
2
4
5
3
1

拿到这个题,我先尝试正面求解,发现有些困难,拿样例来说。
对于输入的第1个数字1,说明求解出来的数列中第2个位置,在它的前面有1个数字比它小。
则对于数对(1,2),(1,3),(1,4),(1,5),(2,3),(2,4)....均是满足条件的,仔细算下的c(n,2)个数对满足条件。
如果以这个为最初状态来进行后面的推演是非常困难的。
正难则反,于是我们倒过来做。
设输入数列为Ai,结果数列为ansi,ansi的数值其实就是在全排列1--N之间找第ai+1小的数字。
每求出一个ansi来后,要将其从全排列1--N之中删除掉。以样例来说
对于输入的倒数第1个数字0,代表要在全排列1--N之间找第1小的数字,明显为1。我们记下这个值并将其从全排列中删除掉。
对于输入的倒数第2个数字1,代表要在全排列2--N之间找第2小的数字,明显为3。我们记下这个值并将其从全排列中删除掉。
对于输入的倒数第3个数字2,代表在数列(2,4,5)中第3小的数字,明显为5.
对于输入的倒数第4个数字1,代表在数列(2,4)中第2小的数字,明显为4.
最后还剩下数字2,易知其为结果数列的第1个数字。于是最终找出来的数列为(2,4,5,3,1),而这个题就本质而言就是一个动态求第K数字的问题,而且数据范围也不大,可以暴力来进行实现。
代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[8010],f[8010],ans[8010];
int main()
{
int n;
scanf("%d",&n);
for(int i=2;i<=n;i++)
scanf("%d",&a[i]);
for(int i=n;i>=1;i--)
{
int sum=0;
for(int j=1;j<=n;j++)
{
if(!f[j])sum++;
if(sum==a[i]+1)
{
ans[i]=j;
f[j]=1;
break;
}
}
}
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}

  

接下来,我就安排学生们来自行书写程序了,但有个学生一直在纸上写写画画,我问他:有什么疑问吗?他说:老师,我觉得这个题正过来做,也是可以的。我有些不耐烦的说:这个题,我研究得很深入了,正着做是不太可能的。但学生仍倔强的说:老师,你再让我试试吧。过了大概15分钟,那个学生说:老师,这个题,我正着做,做过去了,我是这样做的。
我们对于结果数列,不妨设第1个位置为1,然后于输入的1来说,其代表有一个数字比它小,所以可设之为2
于是结果数列为1 2
然后于输入的2来说,其代表有2个数字比它小,所以可设之为3
于是结果数列为1 2 3
然后于输入的1来说,其代表有1个数字比它小,所以可设之为2
于是对前面的1 2 3进行调整,将所有>=2的数字加1
于是结果数列变成1 3 4 2
然后于输入的0来说,其代表有0个数字比它小,所以可设之为1
于是对前面的1 3 4 2进行调整,将所有>=1的数字加1
于是结果数列变成2 4 5 3 1。
代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,a[8000],b[8000],t;
int main(){
cin>>n;
for(int i=2;i<=n;i++){
cin>>a[i];
}
b[1]=1;
for(int i=2;i<=n;i++)
{
b[i]=a[i]+1;
//对于第i个位置来说,在它前面有a[i]个数字比它小,于是可以不考虑其它因素
//这个位置上应该是a[i]+1.
for(int j=1;j<=i-1;j++)
//对于在其左边的数字,如果其权值大于b[i],则对其进行调整
if(b[j]>=b[i])
b[j]++;
}
for(int i=1;i<=n;i++){
cout<<b[i]<<endl;
}
return 0;
}

  

仔细思考下这个学生的求解过程 ,他比我最开始那个想法更进一步的,在于以下两点
1:对于数列的第1个位置上的数来说,它的左边是没有别的数字的,自然也就没有数字比它小。
2:本题是求某个N的全排列,也就是说当N=1时,这个全排列是唯一的,就是数列1。如果N=2,则样例输入就只需要给出1个数字,我们求解出来的,自然也就是一个2的全排列。
于是他的整个求解就有一个扎实的“初状态”,即可以设结果数列的第1个位置就是数字1.
然后根据数据的输入,先去找一个第ai+1小的数字,再对数列进行适当的调整,保证其始终是一个满足题意的N的全排列。

通过这个案例,有以下几点感怀:
首先,学生的创造性是无穷的,永远要去鼓励学生积极探索。
我们的学生都是一个个鲜活的个体,他们天生没有束缚,有着无穷的探索欲。在这一点上,成年人由于接受的知识较多,也就形成了一些条条框框。老师不能以自己的年纪、身份、地位等等因素去打压学生的探索欲,而是应该去鼓励他们积极探索,当然这种探索应该是以理性思考为基础,进行缜密的分析,层层推进。

其次,对于每节课,应该给学生一定的自由。
对于教学来说,最简单最无脑的教法就是老师从头讲到尾,不给学生任何思考的机会。这样的课看似老师很负责任,非常卖力的在讲。但事实上学生接收了多少呢,就算有一定的接收,这种被动的接收,对他的心智的启发又有多大呢?所以对于教学来说,之所以可称之为一门艺术,很大的原因就在于,当面临的学生个体不同,课堂的设计是完全不同的,教学情景如何设计、如何引出问题,引导学生进行分析并进行析疑等等都是非常有讲究的。

关于"丢失的牛"这个题的教学反思的更多相关文章

  1. 洛谷P1588 丢失的牛

    P1588 丢失的牛 158通过 654提交 题目提供者JOHNKRAM 标签USACO 难度普及/提高- 时空限制1s / 128MB 提交  讨论  题解 最新讨论更多讨论 答案下载下来是对的,但 ...

  2. 洛谷——P1588 丢失的牛

    P1588 丢失的牛 题目描述 FJ丢失了他的一头牛,他决定追回他的牛.已知FJ和牛在一条直线上,初始位置分别为x和y,假定牛在原地不动.FJ的行走方式很特别:他每一次可以前进一步.后退一步或者直接走 ...

  3. 【P1588】丢失的牛——区间dp/bfs

    (题面来自Luogu) 题目描述 FJ丢失了他的一头牛,他决定追回他的牛.已知FJ和牛在一条直线上,初始位置分别为x和y,假定牛在原地不动.FJ的行走方式很特别:他每一次可以前进一步.后退一步或者直接 ...

  4. 洛谷 P1588 丢失的牛

    题目描述 FJ丢失了他的一头牛,他决定追回他的牛.已知FJ和牛在一条直线上,初始位置分别为x和y,假定牛在原地不动.FJ的行走方式很特别:他每一次可以前进一步.后退一步或者直接走到2*x的位置.计算他 ...

  5. Oracle数据库对象题库

    一.    填空题 在用 create 语句创建基本表时,最初只是一个空的框架,用户可以使用insert命令把数据插入表中. 在基本表不需要时,可以使用 drop table 语句撤消.在一个基本表撤 ...

  6. USACO翻译:USACO 2014 MARCH Silver三题

    USACO 2014 MARCH 一.题目概览 中文题目名称 农田灌溉 懒牛 牛叫 英文题目名称 irrigation lazy mooomoo 可执行文件名 irrigation lazy mooo ...

  7. 雅礼集训 Day5 T3 题 解题报告

    题 题目背景 由于出题人赶时间所以没办法编故事来作为背景. 题目描述 一开始有\(n\)个苹果,\(m\)个人依次来吃苹果,第\(i\)个人会尝试吃\(u_i\)或\(v_i\)号苹果,具体来说分三种 ...

  8. [算法2-数组与字符串的查找与匹配] (.NET源码学习)

    [算法2-数组与字符串的查找与匹配] (.NET源码学习) 关键词:1. 数组查找(算法)   2. 字符串查找(算法)   3. C#中的String(源码)   4. 特性Attribute 与内 ...

  9. spoj 237

    好牛的题  哈哈 #include <cstdio> #include <algorithm> #define S(n) scanf("%d",&n ...

随机推荐

  1. 云原生的弹性 AI 训练系列之三:借助弹性伸缩的 Jupyter Notebook,大幅提高 GPU 利用率

    Jupyter Notebooks 在 Kubernetes 上部署往往需要绑定一张 GPU,而大多数时候 GPU 并没有被使用,因此利用率低下.为了解决这一问题,我们开源了 elastic-jupy ...

  2. 对epoll机制的学习理解v1

    epoll机制 wrk用非阻塞多路复用IO技术创造出大量的连接,从而达到很好的压力测试效果.epoll就是实现IO多路复用的关键. 本节是对epoll的本质的学习总结,进一步的参考资料为: <深 ...

  3. 分布式全局ID与分布式事务

    1. 概述 老话说的好:人不可貌相,海水不可斗量.以貌取人是非常不好的,我们要平等的对待每一个人. 言归正传,今天我们来聊一下分布式全局 ID 与分布式事务. 2. 分布式全局ID 2.1 分布式数据 ...

  4. 【UE4 调试】提升UE4源码版本Setup下载速度

    更改setup.bat部分参数

  5. 264.丑数II

    题目 给你一个整数 n ,请你找出并返回第 n 个 丑数 . 丑数 就是只包含质因数 2.3 和/或 5 的正整数. 示例 1: 输入:n = 10 输出:12 解释:[1, 2, 3, 4, 5, ...

  6. python的虚拟环境Anaconda使用

    Anaconda 使用conda常用命令   1.首先在所在系统中安装Anaconda.可以打开命令行输入conda -V检验是否安装以及当前conda的版本. 2.conda常用的命令. 1)con ...

  7. 单片机STM32学习笔记之寄存器映射详解

    我们知道,存储器本身没有地址,给存储器分配地址的过程叫存储器映射,那什么叫寄存器映射?寄存器到底是什么? 在存储器Block2 这块区域,设计的是片上外设,它们以四个字节为一个单元,共32bit,每一 ...

  8. 深入理解xLua基于IL代码注入的热更新原理

    目前大部分手游都会采用热更新来解决应用商店审核周期长,无法满足快节奏迭代的问题.另外热更新能够有效降低版本升级所需的资源大小,节省玩家的时间和流量,这也使其成为移动游戏的主流更新方式之一. 热更新可以 ...

  9. Linux下文件的三种时间标记:访问时间、修改时间、状态改动时间 (转载)

    在windows下,一个文件有:创建时间.修改时间.访问时间. 而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就 ...

  10. 开发笔记-----Ajax 基础使用

    一.GET 方式的用法: 1 <!--html --> 2 <div class="layui-form"> 3 <div class="l ...