POJ 2718 贪心

8 篇文章 0 订阅
7 篇文章 0 订阅

做了一上午的2718,差点爆炸

做法一:
用到了STL中的next_permutation产生所有的全排列
要使生成的两个数差最小,两个数的位数差肯定小于等于1,产生一个排列之后在中间分开就可以

什么时候详细写一下STL里面产生全排列的写法

/*
    next_permutation
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <time.h>
using namespace std;

int t, cnt, ans;
char arr[10 + 1];
char input[20];

int make(int, int);

int main() {
    //clock_t start, end;
    //freopen("output.txt", "r", stdin);
    //freopen("out1.txt", "w", stdout);
    scanf("%d", &t);
    getchar();
    while (t --) {
        cnt = 0;
        gets(input);
        for (int i = 0;i < strlen(input);++ i)
            if (input[i] != ' ')
                arr[cnt ++] = input[i];
        //printf("cnt: %d\n", cnt);
        //start = clock();
        sort(arr, arr + cnt);
        //for (int i = 0;i < cnt;++ i)
            //printf("%d", arr[i]);
        ans = -1;
        do {
                if (arr[0] == '0' || arr[cnt / 2] == '0' && cnt > 2)
                    continue;
                int temp = abs(make(0, cnt / 2 - 1) - make(cnt / 2, cnt - 1));
                ans = (ans == -1 || ans > temp) ? temp : ans;
        } while(next_permutation(arr, arr + cnt));
        printf("%d\n", ans);
        //end = clock();
        //printf("time:%f\n", (double)(end - start) / CLOCKS_PER_SEC);
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

int make(int a, int b) {
    int temp = 0;
    for(int i = a;i <= b;++ i)
        temp = temp * 10 + arr[i] - '0';
    return temp;
}

做法二:
分情况
如果是偶数的话,枚举所有两个相差最近的数当作两个生成的数的最高位,之后大数不断取剩下的数中最小的数当作下一位,小数不断取剩下的数中最大的数当作下一位,对于每个枚举更新下ans
如果是奇数的话,就不需要枚举最高位了,因为大的那个数最高位一定得取最小的数字,剩下和偶数做法一样不断取最小的数最大的数然后更新ans
然后需要注意在偶数枚举最高位的时候,不能考虑数字0,其他情况下先不考虑0到最后计算差值的时候如果0出现在第一位就和后面数字换一下位置就可以
我也不知道为什么贪心会WA那么多次,大概是我太菜了,把所有数据全部生成出来对比才发现问题,哎.什么时候还再回忆一下对拍咋写

代码又臭又长

/*
    greedy
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <time.h>
using namespace std;

int t, cnt, ans;
char arr[10];
char input[20], num1[10], num2[10];
bool use[10];
int cnt1, cnt2;

int make(char*, int, int);

int main() {
    //clock_t start, end;
    //freopen("output.txt", "r", stdin);
    //freopen("out2.txt", "w", stdout);
    scanf("%d", &t);
    getchar();
    while (t --) {
        ans = -1;
        cnt1 = cnt2 = 0;
        cnt = 0;
        gets(input);
        for (int i = 0;i < strlen(input);++ i)
            if (input[i] != ' ')
                arr[cnt ++] = input[i];
        //printf("cnt: %d\n", cnt);
        //start = clock();
        sort(arr, arr + cnt);
        //for (int i = 0;i < cnt;++ i)
            //printf("%d", arr[i]);
        /*
        do {
                if (arr[0] == '0' || arr[cnt / 2] == '0' && cnt > 2)
                    continue;
                int temp = abs(make(0, cnt / 2 - 1) - make(cnt / 2, cnt - 1));
                ans = (ans == -1 || ans > temp) ? temp : ans;
        } while(next_permutation(arr, arr + cnt));*/
            if(cnt == 2) {
                printf("%d\n", abs(arr[1] - arr[0]));
                continue ;
            }

            int Min = 10000;

            if(cnt % 2) {
                int temp = (cnt - ((cnt % 2) ? 0 : 2)) / 2 + 1;
                for (int i = 0;i < cnt && temp;++ i) {
                    num1[cnt1 ++] = arr[i];
                    -- temp;
                }
                temp = (cnt - ((cnt % 2) ? 0 : 2)) / 2;
                for (int i = cnt - 1;i >= 0 && temp;-- i) {
                    num2[cnt2 ++] = arr[i];
                    -- temp;
                }
                /*printf("Bigger: ");
                for (int j = 0;j < cnt1;++ j)
                    printf("%c ", num1[j]);
                printf("\n");
                printf("Smaller: ");
                for (int j = 0;j < cnt2;++ j)
                    printf("%c ", num2[j]);
                printf("\n");*/
                temp = abs(make(num1, 0, cnt1 - 1) - make(num2, 0, cnt2 - 1));
                ans = temp;
            }
            else {
                for (int i = 0;i < cnt - 1;++ i)
                    if (arr[i] != '0')
                        Min = min(Min, arr[i + 1] - arr[i]);
                for (int i = 0;i < cnt - 1;++ i)
                    if (arr[i] != '0') {
                        if (Min == arr[i + 1] - arr[i])
                        {
                            cnt1 = cnt2 = 0;
                            int temp;
                            memset(use, 0, sizeof(use));
                            use[i + 1] = use[i] = true;
                            num1[cnt1 ++] = arr[i + 1]; // bigger
                            num2[cnt2 ++] = arr[i]; // smaller

                            //printf("cnt1: %d  cnt2: %d\n", cnt1, cnt2);

                            temp = (cnt - ((cnt % 2) ? 0 : 2)) / 2;
                            for (int j = 0;j < cnt && temp;++ j)
                                if (!use[j]) {
                                    num1[cnt1 ++] = arr[j];
                                    -- temp;
                                }
                            temp = (cnt - ((cnt % 2) ? 0 : 2)) / 2;
                            for (int j = cnt - 1;j >= 0 && temp;-- j)
                                if (!use[j]) {
                                    num2[cnt2 ++] = arr[j];
                                -- temp;
                                }
                            /*for (int j = 0;j < cnt1;++ j)
                            printf("%c ", num1[j]);
                            printf("\n");
                            for (int j = 0;j < cnt2;++ j)
                            printf("%c ", num2[j]);
                            printf("\n");*/
                            temp = abs(make(num1, 0, cnt1 - 1) - make(num2, 0, cnt2 - 1));
                            //printf ("%d\n", temp);
                            ans = (ans == -1 || ans > temp) ? temp : ans;
                        }
                    }
            }
        printf("%d\n", ans);
        //end = clock();
        //printf("time:%f\n", (double)(end - start) / CLOCKS_PER_SEC);
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

int make(char* s ,int a, int b) {
    int temp = 0;
    //printf("%c %c\n", *(s + a), *(s + a + 1));
    if(b - a > 0 && *(s + a) == '0') {
        char tempc = *(s + a);
        *(s + a) = *(s + a + 1);
        *(s + a + 1) = tempc;
    }
    for(int i = a;i <= b;++ i)
        temp = temp * 10 + *(s + i) - '0';
    return temp;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值