杭电1027

来源:互联网 发布:苹果手机默认软件 编辑:程序博客网 时间:2024/05/23 09:46

很简单的一道题,初中时常做,其实就是求第M小的序列
把一些方法放到函数里程序简单一点,但是变量还是显得很乱。
再有就是逻辑是在写的过程中想清楚的,所以错了很多次,这样很不好,还是应该想好再写。
对于这个程序,有两步较重要,就是在交换后,必须保证K后序列为有序且为从小到大。
最后呢,终于对了,还是挺开心!

#include<iostream>using namespace std;void swap(int a[], int x, int y);void sort(int a[], int x, int y);//已知,x到y除y均为从小到大,且y为最小,将其排列为从小到大。int main(){    int fac[10];//计算阶乘小于10000的数字的阶乘值    fac[1] = 1;    for (int i = 2; i <= 9; i++)        fac[i] = fac[i - 1] * i;    int N, M;    while (cin >> N >> M)    {        int num[1001] ;//将1000个数字存放于数组中以利于交换        for (int i = 1; i < 1001; i++)            num[i] = i;        //例如1234  M=6=3!只需234逆序即可,M=7=3!+1那么将1变为2,后面仍为正序即为所求        //M=1时,既为当下那个数,不用进行任何操作,故M=7,经过一次循环得到第七个数然后不再进行任何操作,        //M=9,第一次循环得到第7个序列,然后M=2=2!,第二次循环i=2,将最后两个数逆序即可        //M=9,第一次循环得到第7个序列后,M=3,此时和初始状态去求第3个序列等价(以第7个为基础,去寻求第3个序列)        while (M)         {            int j;            for (j = 1; fac[j] <= M; j++);            j = j - 1;//j!<=M<i!            int k = N - j;//k以后数字变化            int t = M / fac[j];            M = M%fac[j];            if (M)//经过循环变为第t*fac[j]+1个序列//且保证k+1为以后数字为升序            {                swap(num, k, k + t);                sort(num, k+1, k + t);            }            else//如果M就是j的阶乘的整数倍,那么只需要调整第k位的数字,然后将k位以后数字逆序即可            {                swap(num, k, k + t - 1);                sort(num, k+1, k + t - 1);                for (int m = k + 1, n = N; m < n; m++, n--)                    swap(num, m, n);            }        }        //输出        for (int i = 1; i <= N; i++)        {            cout << num[i];            if (i != N)                cout << ' ';        }        cout << endl;    }    return 0;}void swap(int a[], int x, int y){    int temp = a[x];    a[x] = a[y];    a[y] = temp;}void sort(int a[], int x, int y){    if (y > x) {        int temp = a[x];        swap(a, x, y);        for (int i = y; i > x + 1; i--)        {            a[i] = a[i - 1];        }        a[x + 1] = temp;    }}
0 0
原创粉丝点击