不爽,考了两道特坑的很水的贪心题,
写萎了,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;
}
呵呵。。
对贪心绝望了