某天上课讲到这样一个题:
丢失的牛
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. 微信小程序中路由跳转

    一.是什么 微信小程序拥有web网页和Application共同的特征,我们的页面都不是孤立存在的,而是通过和其他页面进行交互,来共同完成系统的功能 在微信小程序中,每个页面可以看成是一个pageMo ...

  2. from athletelist import AthleteList出现红色下滑波浪线警告

    问题:from athletelist import AthleteList出现红色下滑波浪线警告 经过个人网上搜索了解,这个问题是因为python找不到相关的.py文件,无法导入athletelis ...

  3. 从浏览器发送请求给SpringBoot后端时,是如何准确找到哪个接口的?(下篇)

    纸上得来终觉浅,绝知此事要躬行 注意: 本文 SpringBoot 版本为 2.5.2; JDK 版本 为 jdk 11. 前言: 前文:你了解SpringBoot启动时API相关信息是用什么数据结构 ...

  4. LeetCode:并查集

    并查集 这部分主要是学习了 labuladong 公众号中对于并查集的讲解,文章链接如下: Union-Find 并查集算法详解 Union-Find 算法怎么应用? 概述 并查集用于解决图论中「动态 ...

  5. [Beta]the Agiles Scrum Meeting 7

    会议时间:2020.5.21 20:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 issue yjy 暂无 tq 新增功能:添加.选择.展示多个评测机,对新增功能进行测试 评测部分增加 ...

  6. 【Azure Redis 缓存】Windows版创建 Redis Cluster 实验 (精简版)

    简介 学习Redis Cluster的第一步,即本地搭建Redis Cluster.但是在Redis的官方文档中,是介绍在Linux系统中搭建Redis Cluster.本文主要介绍在Windows系 ...

  7. 浅谈如何爆踩TLEcoders

    对付一些速度比老奶奶都慢的评测姬, 除了超级小的常数,往往还不得不使用一些不算办法的办法 比如说这个让人无语的$ACcoders$的评测姬, 当我们感到代码已经无法再卡常的时候,对人生已经近乎绝望的时 ...

  8. CodeForces-1076E Vasya and a Tree

    CodeForces - 1076E Problem Description: Vasya has a tree consisting of n vertices with root in verte ...

  9. [源码解析] Pytorch 如何实现后向传播 (3)---- 引擎动态逻辑

    [源码解析] Pytorch 如何实现后向传播 (3)---- 引擎动态逻辑 目录 [源码解析] Pytorch 如何实现后向传播 (3)---- 引擎动态逻辑 0x00 摘要 0x01 前文回顾 0 ...

  10. 二进制小数 牛客网 程序员面试金典 C++ Python

    二进制小数 牛客网 程序员面试金典 题目描述 有一个介于0和1之间的实数,类型为double,返回它的二进制表示.如果该数字无法精确地用32位以内的二进制表示,返回"Error". ...