UVa 120 - Stacks of Flapjacks

传送门UVa 120 - Stacks of Flapjacks

题意是给你一串数字, 可以选择一个位置翻转, 但是底部的数字不能变, 要求让你输出直到数字排成从小到大的每一步骤所代表的数字.

一开始准备把输入变成字符串, 然后直接一个strrev就翻转了, 方便快捷....直到后来写完了, 代入测试数据的时候才发现这样做是错的.如果输入40的话翻一下就变成04了, 然后我又瞬间想到前几天C++课堂测验也是叫我们翻转一个数组, 我就用这种方法写了

(╯‵□′)╯  ┴─┴ 

没办法, 只好把字符串改为数组, 好在其他地方不用什么大改, 加一个反转的函数就可以了.


这题的算法一开始也想了很久. 说起来也很简单, 我的想法是另外建一个数组, 按照从小到大排序, 之后一个数字一个数字和原数组对照起来, 如果在位置 i 不同的话就翻转一下, 如果翻转一下还是不同, 再翻回来, 找到那个数字, 翻一下, 再翻一下位置 i .以此类推, 直到扫描完一遍数组. 程序结束.


因为我一开始是用strrev做的, 为了函数的方便使用, 我就把原数组翻转了一下, 把目标数组也翻转了一下. 这里请大家无视....


PS:做完这题已经晚上12点了, 提交了一下, 等了5分钟, 还是没有结果. 果断上床了...但是不知道结果根本睡不着, 于是用手机颤抖着打开UVa, 点开My Submission...当我看到那七个字母时候的感觉...真是...爽啊...终于可以睡好觉了..


#include <cstdio>
#include <cstdlib>
#include <cstring>

int temp[100];
int num[100];

int comp(const void *_a, const void *_b)
{
    int *a = (int *)_a;
    int *b = (int *)_b;
    return *b - *a;
}
void Rev(int i, int k)
{
    int k1 = k - 1; //k1为数组最大下标
    int i1 = i;
    for (int l = 0; l < (k - i) / 2; l++)
    {
        int a = temp[i1];
        temp[i1++] = temp[k1];
        temp[k1--] = a;
    }
}

int main()
{
    //freopen("input.txt", "r", stdin);
    int i, j;
    int flag;
    char ch;
    int k;
    while (scanf("%d%c", &temp[0], &ch) == 2)
    {
        k = 1;
        while (ch != '\n')
            scanf("%d%c", &temp[k++], &ch);
        int cnt = 1;
        int fflag = 0;
        for (i = 0; i < k; i++)
        {
            if (fflag == 1)
                printf(" ");
            printf("%d", temp[i]);
            fflag = 1;

        }
        printf("\n");
        Rev(0, k);
        for (i = 0; i < k; i++) //转移元素
            num[i] = temp[i];
        qsort(num, k, sizeof(num[0]), comp);  //num为排序后的数组.
        for (i = 0; i < k; i++)
        {
            if (temp[i] != num[i])      //目标序列为54321, 从头开始搜索.
            {
                flag = 0;
                Rev(i, k);       //翻一下对应位置.
                if (temp[i] != num[i])      //如果翻过来不相等, 翻回去
                    Rev(i, k);
                else      //如果翻过来相等, 输出位置
                {
                    printf("%d ", i + 1);
                    flag = 1;
                }
                if (flag == 0)      //如果翻一下没找到, 找到目标数字, 翻一下, 再从当前位置开始翻
                {
                    for (j = i; j < k; j++)
                    {
                        if (temp[j] == num[i])
                        {
                            Rev(j, k);
                            printf("%d ", j + 1);
                            i--;
                            break;
                        }
                    }
                }
            }
        }
        printf("0\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值