内容:
由1开始之连续数字a1.a2.a3...an相对有一反转表:b1.b2...bm。其bm代表意思为:数字m的位置前面有几个比大个个数。
2 3 6 4 0 2 2 1 0
第1个2为1前面有2个比它大的数
第2个3为2前面有3个比它大的数
第3个6为3前面有6个比它大的数....以此类推
所以答案为
5 9 1 8 2 6 4 7 3
数字1前面有2个比它大的数 5 9
数字2前面有3个比它大的数 5 9 8
输入说明:
输入的每一行含有一个由m个数所组成的数列(反转表) 1<=m<=50,
单独一个 -1 在一行代表测试资料的结束
输出说明:
请输出从 1 到 m 所代表的数列
范例输入:
2 3 6 4 0 2 2 1 0
-1
范例输出 :
5 9 1 8 2 6 4 7 3
------解决方案--------------------------------------------------------
全排列肯定能计算出结果来,不过复杂度是O(n!),肯定是慢的不行了。
全排列的写法:
using System;
namespace ConsoleApplication3
{
class Program
{
static void permlist(int[] listdata, int k, int m)
{
if (k == m)
{
for (int i = 0; i <= m; i++)
{
Console.Write(listdata[i]);
}
Console.WriteLine();
}
else
for (int i = k; i <= m; i++)
{
Swap(ref listdata[k], ref listdata[i]);
permlist(listdata, k + 1, m);
Swap(ref listdata[k], ref listdata[i]);
}
}
static void Swap(ref int a, ref int b)
{
int temp = a; a = b; b = temp;
}
static void Main(string[] args)
{
int[] listdata = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
permlist(listdata, 0, 9);
Console.ReadLine();
}
}
}
------解决方案--------------------------------------------------------
数学归纳法,先口算+笔算,得到规律,再实验,也有人称“驴式思考”:
1,从输入2 3 6 4 0 2 2 1 0 看,第一个数字是2,那么得到了a是{??1?????? },因为1前边有2个比1大的,所以1只能排在第3个。
//得到了a是{??1?????? }
2,第二个数字是3,那么得到了a是{??1?2???? }
依次口算,用笔记录得到
a是{??1?2???3 }
得到了a是{??1?2?4?3 }
得到了a是{5?1?2?4?3 }
得到了a是{5?1?264?3 }
得到了a是{5?1?26473 }
得到了a是{5?1?26473 }
3,根据规律,心中有个大概的公式,尝试写代码
using System;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
int[] b = new int[] { 2, 3, 6, 4, 0, 2, 2, 1, 0 };
int n = b.Length;
int[] a = new int[n];
for (int i = 0; i < n; i++)
{
//假设索引是这个数字
int index = b[i] ;
for (int j = 0; j <= index ; j++)
{
if (a[j]!=0)
{
index++;
}
}
a[index] = i + 1;
}
for (int i = 0; i < a.Length; i++)
{
Console.WriteLine(a[i]);
}
Console.ReadLine();
}
}
}
//实验成功
数学归纳法是常用的一种证明算法正确性的方法。
同样的,可以作为一种常见方法应用于程序正确性的证明
1.初始条件成立
2.程序执行过程中每一步符合某个不变式,这个不变式通常与程序期望结果符合的。
3.程序能够终止,并且终止的时候不变式的成立能够 和程序的期望结果符合。
(例如:一个满头秀发的人,不管他掉多少根头发,都不会不是秃头,这样就是悖论,因为不满足第3条)
这是很重要的思维方式,希望LZ以后多加利用,例如:
排列: 从n个对象中选出m个作为一种排列, 有A(n,m)种; 当m=n时,相当于求n个对象的全排列, 有n!种
组合: 从n个对象中选出m个作为一种组合, 有C(n,m)种; 当m=n时,只有一种.
这样的思路就可以写出排列和组合的输出算法。
归纳法的思想是很强的, c 程序书上, 简单的如求n的阶乘, 复杂的如汉诺塔. 特别是汉诺塔,九连环的问题,
不用递归的方法,很难解决这个古典难题. 但是汉诺塔的递归程序只有不到6,7行.