两道坑爹的贪心题

来源:互联网 发布:seo外链专员 编辑:程序博客网 时间:2024/06/06 01:45

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

写萎了,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 500using 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;}

呵呵。。

对贪心绝望了

0 0