zoukankan      html  css  js  c++  java
  • ZJOI2014 2048

    Description

    提交答案题,写个2048 AI 告诉你随机数生成方式.

    Sol

    xjblg+A*.

    首先我写了个模拟,2048.

    然后自己YY就可以啦...各种乱搞...

    因为随机数,一个最好的状态一定只由一种状态得到,但最初的状态可能转移到多个价值差不多的状态,需要多搜几个..

    于是我用队列来卡队列大小...剩下的就是估价函数了.

    写估价函数的时候一个蛇形递增的序列权值必然需要很高.

    最大权值也有一定权值,因为毕竟要合起来,但是合起来又不一定是最优的,价值适当.

    我自己还乱搞了几个,比如空格子个数,相邻相同数字的个数,这个多了可以一步全部合起来来获得更多的空格子.

    然后把2048的大模拟封装成结构体写头文件里,表示一个状态.

    最后就是跑了...32768应该都可以跑出来,而且比较快,开 O2 跑的更快.

    某ISA还把数据加强了,要求跑出65534,我说这个也是可以的,不确定每个种子都能跑出来,不过大部分应该是可以跑出来的.

    剩下的就是贴代码了...

    Code

    2048.cpp

    #include<cstdio>
    #include<conio.h>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    using namespace std;
    
    const int N = 4;
    const int M = 16;
    const int MUL = 8221;
    
    int seq;
    int w[M];
    FILE *fout=fopen("log.out","w");
    
    void initSeed(int seed){ seq = seed; }
    int GetRand(){ return (seq = (seq * MUL) + (seq >> 16)) & 15; }
    //1 w 2 s 3 a 4 d
    int Read(char ch=getch()){
    	if(isascii(ch)){
    		switch(ch){
    			case 'w':case 'W':return 1;
    			case 's':case 'S':return 2;
    			case 'a':case 'A':return 3;
    			case 'd':case 'D':return 4;
    		}
    	}else{
    		ch=getch();
    		switch(ch){
    			case 72:return 1;
    			case 75:return 3;
    			case 77:return 4;
    			case 80:return 2;
    		}
    	}return -1;
    }
    void GetW(int x=GetRand()){ for(;w[x];x=GetRand());w[x]=2; }
    void Up(int a[]){
    	int u[5],b[5];
    	for(int i=0,j,c,t;i<4;i++){
    		memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    		for(c=0,j=i;j<16;j+=4) if(a[j]) b[++c]=a[j],a[j]=0;
    		for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
    		for(j=1,t=i;j<=c;j++) if(!u[j]) a[t]=b[j],t+=4;
    	}
    }
    void Down(int a[]){
    	int u[5],b[5];
    	for(int i=0,j,c,t;i<4;i++){
    		memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    		for(c=0,j=i+12;j>=0;j-=4) if(a[j]) b[++c]=a[j],a[j]=0;
    		for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
    		for(j=1,t=i+12;j<=c;j++) if(!u[j]) a[t]=b[j],t-=4;
    	}
    }
    void Left(int a[]){
    	int u[5],b[5];
    	for(int i=0,j,c,t;i<16;i+=4){
    		memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    		for(c=0,j=i;j<i+4;j++) if(a[j]) b[++c]=a[j],a[j]=0;
    		for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
    		for(j=1,t=i;j<=c;j++) if(!u[j]) a[t]=b[j],t++;
    	}
    }
    void Right(int a[]){
    	int u[5],b[5];
    	for(int i=0,j,c,t;i<16;i+=4){
    		memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    		for(c=0,j=i+3;j>=i;j--) if(a[j]) b[++c]=a[j],a[j]=0;
    		for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
    		for(j=1,t=i+3;j<=c;j++) if(!u[j]) a[t]=b[j],t--;
    	}
    }
    
    void Copy(int a[],int b[]){ for(int i=0;i<16;i++) b[i]=a[i]; }
    int check(int a[],int b[]){ for(int i=0;i<16;i++) if(a[i]!=b[i]) return 1;return 0; }
    
    void Out(){
    	system("cls");
    	for(int i=1;i<=8;i++) putchar('
    ');
    	for(int i=0;i<M;i++){
    		if(!w[i]) printf("    -%c"," 
    "[(i+1)%4 == 0]);
    		else printf("%5d%c",w[i]," 
    "[(i+1)%4 == 0]);
    	}
    }
    int Over(){
    	int t[M];
    	Copy(w,t),Up(t);if(check(w,t)) return 0;
    	Copy(w,t),Down(t);if(check(w,t)) return 0;
    	Copy(w,t),Left(t);if(check(w,t)) return 0;
    	Copy(w,t),Right(t);if(check(w,t)) return 0;
    	return 1;
    }
    void Print(char c){ fprintf(fout,"%c",c); }
    void Play(int x){
    	initSeed(x),GetW(),GetW(),Out();
    	int cp[M];
    	for(;;){
    		int od=Read(),f=0;
    		switch(od){
    			case 1:Copy(w,cp),Up(cp);if(check(w,cp)) Up(w),f=1,Print('U');break;
    			case 2:Copy(w,cp),Down(cp);if(check(w,cp)) Down(w),f=1,Print('D');break;
    			case 3:Copy(w,cp),Left(cp);if(check(w,cp)) Left(w),f=1,Print('L');break;
    			case 4:Copy(w,cp),Right(cp);if(check(w,cp)) Right(w),f=1,Print('R');break;
    		}
    		if(f) GetW();
    		if(!Over()) Out();
    		else{ puts("You lose!");return; }
    	}
    }
    int main(){
    	for(int x;;){
    		cin>>x;
    		Play(x);
    	}return 0;
    }
    

      

    _2048.h

    #include<cstdio>
    #include<conio.h>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    using namespace std;
    
    #define G(i,j) ((i-1)*4+j-1)
    const int N = 4;
    const int M = 16;
    const int MUL = 8221;
    const double SmoothVal = 17;
    const double MonoVal = 100;
    const double SpaceVal = 5;
    const double MaxVal = 3;
    
    struct S{
    	int seq,maxn,lst;double val;
    	int w[M];
    	//1 w 2 s 3 a 4 d
    	void initSeed(int seed){ seq = seed;memset(w,0,sizeof(w)); }
    	int GetRand(){ return (seq = (seq * MUL) + (seq >> 16)) & 15; }
    	void GetW(){ int x=GetRand();for(;w[x];x=GetRand());w[x]=2; }
    	void Up(int a[]){
    		int u[5],b[5];
    		for(int i=0,j,c,t;i<4;i++){
    			memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    			for(c=0,j=i;j<16;j+=4) if(a[j]) b[++c]=a[j],a[j]=0;
    			for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
    			for(j=1,t=i;j<=c;j++) if(!u[j]) a[t]=b[j],t+=4;
    		}
    	}
    	void Down(int a[]){
    		int u[5],b[5];
    		for(int i=0,j,c,t;i<4;i++){
    			memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    			for(c=0,j=i+12;j>=0;j-=4) if(a[j]) b[++c]=a[j],a[j]=0;
    			for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
    			for(j=1,t=i+12;j<=c;j++) if(!u[j]) a[t]=b[j],t-=4;
    		}
    	}
    	void Left(int a[]){
    		int u[5],b[5];
    		for(int i=0,j,c,t;i<16;i+=4){
    			memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    			for(c=0,j=i;j<i+4;j++) if(a[j]) b[++c]=a[j],a[j]=0;
    			for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
    			for(j=1,t=i;j<=c;j++) if(!u[j]) a[t]=b[j],t++;
    		}
    	}
    	void Right(int a[]){
    		int u[5],b[5];
    		for(int i=0,j,c,t;i<16;i+=4){
    			memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    			for(c=0,j=i+3;j>=i;j--) if(a[j]) b[++c]=a[j],a[j]=0;
    			for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
    			for(j=1,t=i+3;j<=c;j++) if(!u[j]) a[t]=b[j],t--;
    		}
    	}	
    	void Find(){
    		maxn=lst=0;
    		for(int i=0;i<M;i++) if(w[i]) lst++,maxn=max(w[i],maxn);
    	}
    	void Copy(int a[],int b[]){ for(int i=0;i<M;i++) b[i]=a[i]; }
    	int check(int a[],int b[]){ for(int i=0;i<M;i++) if(a[i]!=b[i]) return 1;return 0; }
    	int Over(){
    		int t[M];
    		Copy(w,t),Up(t);if(check(w,t)) return 0;
    		Copy(w,t),Down(t);if(check(w,t)) return 0;
    		Copy(w,t),Left(t);if(check(w,t)) return 0;
    		Copy(w,t),Right(t);if(check(w,t)) return 0;
    		return 1;
    	}
    	void Order(int x){
    		switch(x){
    			case 1:Up(w);break;
    			case 2:Down(w);break;
    			case 3:Left(w);break;
    			case 4:Right(w);break;
    		}
    	}
    	void Print(){
    		for(int i=0;i<M;i++)
    			if(!w[i]) printf("    -%c"," 
    "[(i+1)%4 == 0]);
    			else printf("%5d%c",w[i]," 
    "[(i+1)%4 == 0]);
    		putchar('
    ');
    	}
    	int abs(int x){ return x<0?-x:x; }
    	int Smooth(){
    		int res=0x7fffffff,tmp=0;
    		int b1[]={ 0,1,2,3,7,6,5,4,8,9,10,11,15,14,13,12 };
    		int b2[]={ 3,2,1,0,4,5,6,7,11,10,9,8,12,13,14,15 };
    		int b3[]={ 12,13,14,15,11,10,9,8,4,5,6,7,3,2,1,0 };
    		int b4[]={ 15,14,13,12,8,9,10,11,7,6,5,4,0,1,2,3 };
    		int b5[]={ 0,4,8,12,13,9,5,1,2,6,10,14,15,11,7,3 };
    		int b6[]={ 12,8,4,0,1,5,9,13,14,10,6,2,3,7,11,15 };
    		int b7[]={ 3,7,11,15,14,10,6,2,1,5,9,13,12,8,4,0 };
    		int b8[]={ 15,11,7,3,2,6,10,14,13,9,5,1,0,4,8,12 };
    		
    		for(int i=0;i<M-1;i++) if(w[b1[i]] && w[b1[i+1]]) tmp+=abs(w[b1[i]]-w[b1[i+1]]*2);
    		if(w[b1[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
    		for(int i=0;i<M-1;i++) if(w[b2[i]] && w[b2[i+1]]) tmp+=abs(w[b2[i]]-w[b2[i+1]]*2);
    		if(w[b2[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
    		for(int i=0;i<M-1;i++) if(w[b3[i]] && w[b3[i+1]]) tmp+=abs(w[b3[i]]-w[b3[i+1]]*2);
    		if(w[b3[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
    		for(int i=0;i<M-1;i++) if(w[b4[i]] && w[b4[i+1]]) tmp+=abs(w[b4[i]]-w[b4[i+1]]*2);
    		if(w[b4[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
    		for(int i=0;i<M-1;i++) if(w[b5[i]] && w[b5[i+1]]) tmp+=abs(w[b5[i]]-w[b5[i+1]]*2);
    		if(w[b5[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
    		for(int i=0;i<M-1;i++) if(w[b6[i]] && w[b6[i+1]]) tmp+=abs(w[b6[i]]-w[b6[i+1]]*2);
    		if(w[b6[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
    		for(int i=0;i<M-1;i++) if(w[b7[i]] && w[b7[i+1]]) tmp+=abs(w[b7[i]]-w[b7[i+1]]*2);
    		if(w[b7[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
    		for(int i=0;i<M-1;i++) if(w[b8[i]] && w[b8[i+1]]) tmp+=abs(w[b8[i]]-w[b8[i+1]]*2);
    		if(w[b8[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
    		return res;
    //		for(int i=1;i<=4;i++) for(int j=1;j<=3;j++) if(w[G(i,j)] && w[G(i,j+1)] && w[G(i,j)] > w[G(i,j+1)]) tmp+=w[G(i,j)]-w[G(i,j+1)]*2;
    //		res=min(res,tmp),tmp=0;
    //		for(int i=1;i<=4;i++) for(int j=1;j<=3;j++) if(w[G(i,j)] && w[G(i,j+1)] && w[G(i,j)] < w[G(i,j+1)]) tmp+=w[G(i,j+1)]-w[G(i,j)]*2;
    //		res=min(res,tmp),tmp=0;
    //		for(int j=1;j<=4;j++) for(int i=1;i<=3;i++) if(w[G(i,j)] && w[G(i+1,j)] && w[G(i,j)] > w[G(i+1,j)]) tmp+=w[G(i,j)]-w[G(i+1,j)]*2;
    //		res=min(res,tmp),tmp=0;
    //		for(int j=1;j<=4;j++) for(int i=1;i<=3;i++) if(w[G(i,j)] && w[G(i+1,j)] && w[G(i,j)] < w[G(i+1,j)]) tmp+=w[G(i+1,j)]-w[G(i,j)]*2;
    //		return min(res,tmp);
    	}
    	int Mono(){
    		int res=0,tmp=0;
    		for(int i=1;i<=4;i++) for(int j=1;j<=3;j++) if(w[G(i,j)] < w[G(i,j+1)]) tmp++;
    		for(int i=1;i<=4;i++) for(int j=1;j<=3;j++) if(w[G(i,j)] > w[G(i,j+1)]) tmp--;
    		if(tmp < 0) tmp*=-1;
    		for(int j=1;j<=4;j++) for(int i=1;i<=3;i++) if(w[G(i,j)] < w[G(i+1,j)]) res++;
    		for(int j=1;j<=4;j++) for(int i=1;i<=3;i++) if(w[G(i,j)] > w[G(i+1,j)]) res--;
    		if(res < 0) res*=-1;
    		return max(res,tmp);
    	}
    	int Space(){
    		int cnt=0;double r=0,h=0,sr=0,sh=0;
    		for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(!w[G(i,j)]) sr+=i,sh+=j,cnt++;
    		sr=sr/cnt,sh=sh/cnt;
    		for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(!w[G(i,j)]) r+=(sr-i)*(sr-i),h+=(sh-j)*(sh-j);
    		return (int)(r+h)*(16-lst);
    	}
    	void GetVal(){
    		val = 0;
    		val -= Smooth() * SmoothVal;
    		val += Mono() * MonoVal;
    		val -= Space() * SpaceVal;
    		val += maxn * MaxVal;
    /*		int u[5],b[5];
    		for(int i=0,j,c;i<4;i++){
    			memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    			for(c=0,j=i;j<16;j+=4) if(w[j]) b[++c]=w[j];
    			for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1,tmp+=b[j];
    		}
    		val=max(val,tmp),tmp=0;
    		for(int i=0,j,c;i<4;i++){
    			memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    			for(c=0,j=i+12;j>=0;j-=4) if(w[j]) b[++c]=w[j];
    			for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1,tmp+=b[j];
    		}
    		val=max(val,tmp),tmp=0;
    		for(int i=0,j,c;i<16;i+=4){
    			memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    			for(c=0,j=i;j<i+4;j++) if(w[j]) b[++c]=w[j];
    			for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1,tmp+=b[j];
    		}
    		val=max(val,tmp),tmp=0;
    		for(int i=0,j,c;i<16;i+=4){
    			memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
    			for(c=0,j=i+3;j>=i;j--) if(w[j]) b[++c]=w[j];
    			for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1,tmp+=b[j];
    		}*/
    		return;
    	}
    };
    

    main.cpp

    #include "_2048.h"
    #include<utility>
    #include<vector>
    #include<windows.h>
    #include<queue>
    #include<stack>
    #include<algorithm>
    using namespace std;
    
    #define mpr(a,b) make_pair(a,b)
    const int Q = 2048;
    
    queue<S> q;
    vector<pair<int,int> > f;
    int cnt;
    
    void Out(int x){
    	stack<int> stk;
    //	cout<<x<<endl;
    	for(pair<int,int> y=f[x];;y=f[y.first]){
    		stk.push(y.second);
    //		cout<<y.second<<endl;
    		if(y.first == 0) break;
    	}
    	for(;!stk.empty();stk.pop()){
    		switch(stk.top()){
    			case 1:putchar('U');break;
    			case 2:putchar('D');break;
    			case 3:putchar('L');break;
    			case 4:putchar('R');break;
    		}
    	}
    }
    void BFS(S &a){
    	q.push(a);int tmp=0;
    	f.push_back(mpr(0,0));
    	for(S t,s[5];!q.empty();++tmp){
    //		Sleep(120);
    		t=q.front(),q.pop();
    //		t.Print();
    		if(t.Find(),t.maxn >= 60000){ Out(tmp);return; }
    		if(t.Over()) continue;
    		
    		vector<pair<double,int> > A;
    		
    		for(int i=1;i<=4;i++){
    			s[i].initSeed(t.seq);
    			s[i].Copy(t.w,s[i].w);
    			s[i].Order(i);
    			if(!s[i].check(s[i].w,t.w)){ continue; }
    			s[i].Find();
    //			if(s[i].maxn >= 60000){ Out(tmp);cout<<i<<endl;return; }
    			if(s[i].Over()) continue;
    			s[i].GetW();
    			if(s[i].Over()) continue;
    			s[i].GetVal();
    			A.push_back(mpr(s[i].val,i));
    //			s[i].Print();
    //			q.push(s[i]);
    //			f.push_back(mpr(tmp,i));
    		}
    		
    		sort(A.begin(),A.end());
    		for(int i=A.size()-1;i>=0 && q.size()<Q && i+3>A.size();i--){
    			q.push(s[A[i].second]);
    //			s[A[i].second].Print(),printf("%lf
    ",s[A[i].second].val);
    			f.push_back(mpr(tmp,A[i].second));
    		}
    //		cout<<"***********"<<endl;
    //		for(int i=A.size()-1;i>=0;i--) s[A[i].second].Print(),printf("%lf
    ",s[A[i].second].val);
    //		cout<<"***********"<<endl;
    	}
    }
    
    int main(){
    	freopen("204820.out","w",stdout);
    	S fff;
    	fff.initSeed(20);
    	fff.GetW(),fff.GetW();
    //	fff.Print();
    	BFS(fff);
    	return 0;
    }
    

      

  • 相关阅读:
    SpringCloud整合过程中jar依赖踩坑经验
    spring-boot-starter-parent的主要作用
    配置Setting.xml文件提高maven更新下载jar包速度
    剑指Offer-编程详解-二维数组中的查找
    Git 拉取Gitee仓库报错:“fatal: unable to access ''": Failed to connect to 127.0.0.1 port 1080: Connection refused”
    SpringBoot整合mybatis——配置mybatis驼峰命名规则自动转换
    SpringBoot 整合 Mybatis + Mysql——XML配置方式
    ES+open-falcon之nginx状态码监控报警自动化
    zabbix告警邮件美化
    基于Jenkins+Gitlab的自动化部署实战
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6052090.html
Copyright © 2011-2022 走看看