您的位置:首页 > 其它

poj 1069 dfs(难在建立一个坐标)

2015-09-14 17:24 357 查看


<span style="color:#009900;">/*题意:就是给你1到25边长大小的三角形 你可以无限使用 问能不能构成一个大小为<=10的正六边形*/
/*思路:首先是坐标的变换 坐标变换好了 就是一样的做了 因为呈现的是60的角度 我想都学过坐标转换 由于是成60度的角 所以
我们可以把这个放在图上表示为 一个小三角形表示为一个点 坐标的建立如上图所示*/</span>

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pp;
#define inf 0x3f3f3f3f
#define eps 1e-10
#define maxl 100
#define mem(i,j) memset(i,j,sizeof(i))
const int mod=1e9+7;
int p[maxl][maxl];
int e,len[maxl],vis[maxl];
vector<int> v;

void init(){//对照图的话就很好初始化坐标了
memset(p,0,sizeof(p));
for(int i=1;i<=e;i++)
for(int j=1;j<=2*e+2*i-1;j++)
p[i][j]=1;
for(int i=e+1;i<=2*e;i++)
for(int j=2*(i-e);j<=4*e;j++)
p[i][j]=1;
}

bool ok(){
for(int i=0;i<v.size();i++){
if(e%v[i]==0) return true;
}
return false;
}

bool judge(int x,int y,int z){
if(x+z-1>2*e||y+2*z-2>4*e) return false; //这一步剪枝需要画图实践
if(y%2){
for(int i=0;i<z;i++)
for(int j=0;j<2*i+1;j++)//一定要注意 这里找了半天bug发现2*i+1 写成了2*i-1
if(!p[x+i][y+j]) return false;
}
else{
for(int i=0;i<z;i++)
for(int j=2*i;j<2*z-1;j++)
if(!p[x+i][y+j]) return false;
}
return true;
}

void turn(int x,int y,int z){//翻转
if(y%2){
for(int i=0;i<z;i++)
for(int j=0;j<2*i+1;j++)
p[x+i][y+j]=0;
}
else{
for(int i=0;i<z;i++)
for(int j=2*i;j<2*z-1;j++)
p[x+i][y+j]=0;
}
}

void turnagain(int x,int y,int z){//翻回来
if(y%2){
for(int i=0;i<z;i++)
for(int j=0;j<2*i+1;j++)
p[x+i][y+j]=1;
}
else{
for(int i=0;i<z;i++)
for(int j=2*i;j<2*z-1;j++)
p[x+i][y+j]=1;
}
}

bool dfs(int i,int j){
if(i>2*e) return true;
if(j>4*e) return dfs(i+1,1);//因为这里是从1开始的 所以下面要检查一下
if(!p[i][j])
int k;
for(k=j+1;k<=4*e;k++){
if(p[i][k]) break;
}
return dfs(i,k);
}
for(int k=0;k<v.size();k++){
if(judge(i,j,v[k])){
turn(i,j,v[k]);
if(dfs(i,j+1)) return true;
turnagain(i,j,v[k]);
}
else break;//这里神奇的剪枝 大的肯定放不下了
}
return false;
}

int main()
{
freopen("in.txt", "r", stdin);
int t;
cin>>t;
while(t--){
int num;
cin>>e>>num;
for(int j=0;j<num;j++) cin>>len[j];
sort(len,len+num);
memset(vis,0,sizeof(vis));
v.clear();
for(int j=0;j<num;j++){
for(int k=j+1;k<num;k++){
if(!vis[k]&&len[k]%len[j]==0) vis[k]=1;
}
}
for(int j=0;j<num;j++) if(!vis[j]){v.push_back(len[j]);}//去重
if(ok()){cout<<"YES"<<endl;continue;}//剪枝
init();
if(dfs(1,1)) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: