CERC2014 Can't stop playing(一维2048)

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4943

注意点蛮多的。。。数列大小一定是先上升后下降的,也就是“^”形状。所以可以分成左右两部分s1,s2。注意剪枝。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <assert.h>
using namespace std;
int n;
int sum[1003], x[1003];
bool vis[1003][(1 << 13) + 1];
char ans[1003];
int highBit[1 << 14];
int dfs(int p,int s1){
	int s2=(p==0?0:sum[p-1])-s1;
	if(p==n){
		if(s1==highBit[s1]&&s2==highBit[s2]&&(s1+s2)==highBit[s1+s2]){
			return 1;
		}
		return 0;
	}
	if(vis[p][s1]||vis[p][s2]) 
		return 0;
	vis[p][s1]=1;
	vis[p][s2]=1;
	int u=14,uu=0,a,b;
	for(int i=0;i<=13;++i){
		if(s1&(1<<i)){
			u=i;
			break;
		}
	}	
	if((1<<u)>=x[p]){
		a=s1+x[p];b=s2;
		if(highBit[a]==highBit[b])
			a-=highBit[a],b+=highBit[a]; //判断向左/右推的时候s1最高点和s2最高点会不会合并 
		if(dfs(p+1,a)==1)
			ans[p]='l',uu=1;
	}
	else if(s2==highBit[s2]&&s2>=highBit[s1]){
		a=s1+s2;b=x[p];
		if(highBit[a]==highBit[b])
			a+=highBit[a],b-=highBit[a]; //判断向左/右推的时候s1最高点和s2最高点会不会合并 
		if(dfs(p+1,a)==1)
			ans[p]='r',uu=1;
	}
	u=14;
	for(int i=0;i<=13;++i){
		if(s2&(1<<i)){
			u=i;
			break;
		}
	}
	if((1<<u)>=x[p]){
		a=s1;b=s2+x[p];
		if(highBit[a]==highBit[b])
			a+=highBit[a],b-=highBit[a]; //判断向左/右推的时候s1最高点和s2最高点会不会合并 
		if(dfs(p+1,a)==1)
			ans[p]='r',uu=1;
	}
	else if(s1==highBit[s1]&&s1>=highBit[s2]){
		a=x[p];b=s1+s2;
		if(highBit[a]==highBit[b])
			a-=highBit[a],b+=highBit[a]; //判断向左/右推的时候s1最高点和s2最高点会不会合并 
		if(dfs(p+1,a)==1)
			ans[p]='l',uu=1;
	}
	if(uu==1)
		return 1;
	else
		return 0;
}
int main(){
	for (int i=1;i<(1<<14);i++) 
		if ((i & -i) == i) highBit[i] = i;
		else highBit[i] = highBit[i - 1];
	int t;
	cin>>t;
	while(t--){
		cin>>n;
		for (int i = 0; i < n; i ++)
			memset(vis[i], 0, sizeof vis[i]);
		for(int i=0;i<n;++i)
			cin>>x[i];
		sum[0]=x[0];
		for(int i=1;i<n;++i)
			sum[i]=sum[i-1]+x[i];
		if(dfs(0,0)){
			ans[n]='\0';
			printf("%s\n", ans);
		}
		else
			cout<<"no"<<endl;
	}
	return 0;
}


你可能感兴趣的:(CERC2014 Can't stop playing(一维2048))