【杭二联考】刷怪升级

【杭二联考】刷怪升级

交的

// 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算法,暴力枚举用哪种方式搞,顺便加两个一般人都会加的剪枝:

  1. 代价大于答案时return
  2. 可以直接打死时直接搜下一个
// 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会怎么样。。。

posted @ 2017-08-23 13:41  菜狗xzz  阅读(137)  评论(0编辑  收藏  举报