两道坑爹的贪心题

不爽,考了两道特坑的很水的贪心题,

写萎了,80分  A了  写萎了,只得了80分。。。

题目大意:

一个x*y*z的蛋糕(不是那道有 一堆剪枝 巨坑的  深搜题),最多切k次,将蛋糕切成几小块(每块都是整数),求最大块数。。

于是改一下。。

求乘积最大的满足 a<x b<y c<z 且a+b+c-3<=k的整数a,b,c

懵逼。

于是采用“ 骗分 + 贪心 ”算法,pai来pai去都是对的。。

骗分代码你肯定能看懂!

#include<cstdio>
using namespace std;
int main() {
    freopen("cake.in","r",stdin);
    freopen("cake.out","w",stdout);
    int x,y,z;
    unsigned long long k;
    scanf("%d%d%d%lld",&x,&y,&z,&k);
    unsigned long long maxk=x+y+z-3;
    if(k>=maxk) {
        printf("%lld",(long long)x*y*z);
        return 0;
    }
    int a,b,c;
    a=b=c=1;
    unsigned long long ans=1;
    while(k) {
        --k;
        if(a<x&&b<y&&c<z)
            if(a<b)
                if(a<c) {
                    ans+=b*c;
                    ++a;
                } else {
                    ans+=a*b;
                    ++c;
                }
            else if(b<c) {
                ans+=a*c;
                ++b;
            } else {
                ans+=a*b;
                ++c;
            }
        else if(a<x&&b<y)
            if(a<b) {
                ans+=b*c;
                ++a;
            } else {
                ans+=a*c;
                ++b;
            }
        else if(a<x&&c<z)
            if(a<c) {
                ans+=b*c;
                ++a;
            } else {
                ans+=a*b;
                ++c;
            }
        else if(b<y&&c<z)if(b<c) {
                ans+=a*c;
                ++b;
            } else {
                ans+=a*b;
                ++c;
            }
        else if(a<x) {
            ans+=b*c;
            ++a;
        } else if(b<y) {
            ans+=a*c;
            ++b;
        } else {
            ans+=a*b;
            ++c;
        }
    }
    printf("%lld\n",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

看到std代码后,懵B了。

#include<cstdio>
using namespace std;
int main() {
    freopen("cake.in","r",stdin);
    freopen("cake.out","w",stdout);
    int x,y,z;
    unsigned long long k;
    scanf("%d%d%d%lld",&x,&y,&z,&k);
    while(x+y+z>k+3) {
        if(x>y)
            if(x>z)x--;
            else z--;
        else if(y>z)y--;
        else z--;
    }
    printf("%lld\n",(long long)x*y*z);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

而且瞬间理解!

懵逼。。。


第二道,图的还原。

给定 n 个点,已知每个点的度数

求一种方案,使得这 n 个点构成一个无向图

不能连重边或者自环,保证有解

第一眼表示深搜

于是就有了它

#include<cstdio>
#include<cstdlib>
#define MAXN 500
using namespace std;
int du[MAXN+1];
int e[MAXN*(MAXN-1)+1][2];
bool vis[MAXN+1][MAXN+1];
void dfs(int);
int sum=0,n;
int main() {
	freopen("recover.in","r",stdin);
	freopen("recover.out","w",stdout);
	scanf("%d",&n);
	for(int i=1; i<=n; i++) {
		scanf("%d",&du[i]);
		sum+=du[i];
	}
	sum>>=1;
	dfs(1);
	fclose(stdin);
	fclose(stdout);
	return 0;
}
void print() {
	for(int doorpig=1; doorpig<=sum; ++doorpig)
		printf("%d %d\n",e[doorpig][0],e[doorpig][1]);
	exit(0);
}
void dfs(int doorqyp) {
	if(doorqyp>sum)print();
	for(int i=1; i<n; ++i)
		for(int j=i+1; j<=n; ++j)
			if(!vis[i][j]&&du[i]&&du[j]) {
				du[i]--;
				du[j]--;
				e[doorqyp][0]=i;
				e[doorqyp][1]=j;
				vis[i][j]=vis[j][i]=1;
				dfs(doorqyp+1);
				du[i]++;
				du[j]++;
				vis[i][j]=vis[j][i]=0;
			}
}
然而题解

#include <cstdio>
#include <algorithm>
using namespace std;

int n;
struct ar {
    int x,y;
};
ar a[505];
bool cmp(ar a,ar b) {
    return a.x>b.x;
}

int main() {
    freopen("recover.in","r",stdin);
    freopen("recover.out","w",stdout);
    scanf("%d",&n);
    for (int i=1; i<=n; i++) {
        scanf("%d",&a[i].x);
        a[i].y=i;
    }
    for (int i=1; i<=n; i++) {
        sort(a+1,a+n+1,cmp);
        for (int j=2; a[1].x; j++) {
            printf("%d %d\n",a[1].y,a[j].y);
            a[1].x--;
            a[j].x--;
        }
        a[1].x-=1<<29;
    }
    return 0;
}

呵呵。。

对贪心绝望了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值