【杭二联考】刷怪升级
【杭二联考】刷怪升级
交的
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#define Fname "playwithboss"
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,ans=2e9;
struct data{int a,b,c;}s[100010];
il vd tanxin_random(){
random_shuffle(s+1,s+n+1);
int a=0,b=0,c=0;
rep(i,1,n){
int A=s[i].a-a,B=s[i].b-b,C=s[i].c-c;
if(A<=0||B<=0||C<=0)continue;
if(A<=B&&A<=C)a=s[i].a;
else if(B<=A&&B<=C)b=s[i].b;
else c=s[i].c;
}ans=min(ans,a+b+c);
}
il vd dfs(int k,int A,int B,int C){
if(A+B+C>=ans)return;
if(k==n+1){ans=min(ans,A+B+C);return;}
if(A>=s[k].a||B>=s[k].b||C>=s[k].c){dfs(k+1,A,B,C);return;}
dfs(k+1,s[k].a,B,C);
dfs(k+1,A,s[k].b,C);
dfs(k+1,A,B,s[k].c);
}
int main(){
freopen(Fname".in","r",stdin);
freopen(Fname".out","w",stdout);
n=gi();
rep(i,1,n)s[i].a=gi(),s[i].b=gi(),s[i].c=gi();
if(n<=300)dfs(1,0,0,0);
else {
s[0]=(data){0,0,0};
drep(i,100,0)tanxin_random();
}
printf("%d\n",ans);
return 0;
}
randon_shuffle炸了。。。T成30分
然而。。。这两段代码都能AC
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#define Fname "playwithboss"
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,ans=2e9;
struct data{int a,b,c;}s[100010];
il vd dfs(int k,int A,int B,int C){
if(A+B+C>=ans)return;
if(k==n+1){ans=min(ans,A+B+C);return;}
if(A>=s[k].a||B>=s[k].b||C>=s[k].c){dfs(k+1,A,B,C);return;}
dfs(k+1,s[k].a,B,C);
dfs(k+1,A,s[k].b,C);
dfs(k+1,A,B,s[k].c);
}
int main(){
freopen(Fname".in","r",stdin);
freopen(Fname".out","w",stdout);
n=gi();
rep(i,1,n)s[i].a=gi(),s[i].b=gi(),s[i].c=gi();
dfs(1,0,0,0);
printf("%d\n",ans);
return 0;
}
AC
这是dfs算法,暴力枚举用哪种方式搞,顺便加两个一般人都会加的剪枝:
- 代价大于答案时return
- 可以直接打死时直接搜下一个
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#define Fname "playwithboss"
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,ans=2e9;
struct data{int a,b,c;}s[100010];
il vd tanxin_random(){
random_shuffle(s+1,s+n+1);
int a=0,b=0,c=0;
rep(i,1,n){
int A=s[i].a-a,B=s[i].b-b,C=s[i].c-c;
if(A<=0||B<=0||C<=0)continue;
if(A<=B&&A<=C)a=s[i].a;
else if(B<=A&&B<=C)b=s[i].b;
else c=s[i].c;
}ans=min(ans,a+b+c);
}
int main(){
freopen(Fname".in","r",stdin);
freopen(Fname".out","w",stdout);
n=gi();
rep(i,1,n)s[i].a=gi(),s[i].b=gi(),s[i].c=gi();
s[0]=(data){0,0,0};
rep(i,0,100)tanxin_random();
printf("%d\n",ans);
return 0;
}
AC。。。
完全错误的贪心算法,维护ABC三个变量表示升的攻击。对于每一个怪,选升的最少的来升。
加random_shuffle,跑一百遍。。。
出题人真的在良心出题吗。。。显然错误的贪心算法×100次可以AC,dfs+两个剪枝直接AC,跑的比正解还快。。。
如果考场上有人正解写挂了然后发现有人dfsAC会怎么样。。。
博主是蒟蒻,有问题请指出,谢谢!
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。