半个下午+半个晚上,写的稀烂,各种粗心小错误,今天状态不佳啊。
一个点一个点枚举,判断是否可以放灯的时候就扫他的上下左右是否放过灯,用vis标记放过灯的位置。
放完全图后,再判断是否满足障碍物周围恰有那么多灯。
一个个点枚举过去会产生一个问题,回朔的时候状态太多,所以加一个剪枝:当前点右边,如果是障碍物,那障碍物上面(上面一整条,不是上面那个点)如果都没有灯,则剪掉。
我们是一个个点枚举过去,为什么会产生上面还是空的呢?就是因为加了回朔,
题目没有规定每一行都要有放灯,所以可以一整行一个灯都没有,所以就会出现上面的情况
写的太烂了,看看思路就好,我的代码就直接无视掉吧,900+ms擦边过,贴一下仅供批评。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define min(x,y) x<y?x:y
int map[10][10];
int tmap[10][10];
int vis[10][10];
int n,m,ans;
struct node
{
int x,y,num;
};
vector<node> b;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int N;
bool inmap(int x,int y)
{
return x>=0&&x<n&&y>=0&&y<m;
}
bool can(int r,int c)
{
if(map[r][c]!=-4) return false;
for(int d=0;d<4;d++)
{
int x=r,y=c;
while(inmap(x+dx[d],y+dy[d]))
{
x+=dx[d];
y+=dy[d];
if(vis[x][y]) return false;
if(map[x][y]>=-1) break;
}
}
int nx=r+dx[3],ny=c+dy[3];
if(inmap(nx,ny)&&map[nx][ny]>=-1&&nx>=1)
{
while(inmap(nx+dx[0],ny+dy[0]))
{
if(vis[nx+=dx[0]][ny+=dy[0]])
{
return true;
}
}
return false;
}
return true;
}
void creat(int x,int y)
{
tmap[x][y]=-2;
for(int i=x-1;i>=0;i--)
if(map[i][y]>=-1) break;
else tmap[i][y]=-3;
for(int i=x+1;i<n;i++)
if(map[i][y]>=-1) break;
else tmap[i][y]=-3;
for(int i=y-1;i>=0;i--)
if(map[x][i]>=-1) break;
else tmap[x][i]=-3;
for(int i=y+1;i<m;i++)
if(map[x][i]>=-1) break;
else tmap[x][i]=-3;
}
bool isok()
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
tmap[i][j]=map[i][j];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(vis[i][j]) creat(i,j);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(tmap[i][j]==-4) return false;
for(int i=0;i<b.size();i++)
{
int tot=0;
for(int d=0;d<4;d++)
{
int nx=b[i].x+dx[d];
int ny=b[i].y+dy[d];
if(inmap(nx,ny)&&tmap[nx][ny]==-2)
{
tot++;
}
}
if(tot!=b[i].num)
return false;
}
return true;
}
void dfs(int v,int tot)
{
if(tot>=ans) return;
for(int i=v;i<N;i++)
{
int x=i/m;
int y=i%m;
if(can(x,y))
{
vis[x][y]=1;
dfs(i+1,tot+1);
vis[x][y]=0;
}
}
if(isok())
{
ans=min(tot,ans);
}
}
int main()
{
int t,x,y,v;
node a;
while(scanf("%d%d",&n,&m)&&(n||m))
{
N=n*m;
b.clear();
memset(map,-0x3f,sizeof(map));
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
map[i][j]=-4;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
scanf("%d%d%d",&x,&y,&v);
x--;y--;
map[x][y]=v;
if(v!=-1)
{
a.x=x;a.y=y;a.num=v;
b.push_back(a);
}
}
ans=inf;
dfs(0,0);
if(ans!=inf)
printf("%d\n",ans);
else
printf("No solution\n");
}
return 0;
}
分享到:
相关推荐
POJ-2870 Light Up + DFS(1级DFS+1级DFS) + Python - 思维导图 链接:https://blog.csdn.net/xxdragon126/article/details/122095922?spm=1001.2014.3001.5501
北大POJ3009-Curling 2.0【DFS+Vector+回溯+剪枝】 解题报告+AC代码
北大POJ3733-Changing Digits【DFS+强剪枝】 解题报告+AC代码
北大POJ3373-Changing Digits【DFS+强剪枝】 解题报告+AC代码
西北工业大学POJ试题C++答案代码+课程设计
北大POJ1207-The 3n + 1 problem 解题报告+AC代码
各种搜索算法,配合POJ上的题目,含标程,及各题解题思路。
1011,1012,1013,1014,1015,1017,1026,1028,1032,1035,1041,1046,1129 1149 1154 1165 1182 1185 1190 1191 1201 1251 1273 1275 1276 1286 1322 1338 1363 1364 1401 1456 1459 1564 1579 1637 1657 1658 ...
北大POJ初级-简单搜索 解题报告+AC代码
poj 2488——dfs深度优先遍历 //给行数列数,求问能否遍历,给出字典序的一种遍历
北大POJ1020-Anniversary Cake 解题报告+AC代码
北大POJ1691-Painting A Board 【拓扑+DFS】 解题报告+AC代码
北大POJ1014-Dividing【DFS】【多重背包+二进制优化】 解题报告+AC代码
DFS POJ 2488 POJ 3083 POJ 3009 POJ 1321 BFS POJ 3278 POJ 1426 POJ 3126 POJ 3414 POJ 2251 简单搜索技巧和剪枝 POJ 1010 :star: POJ 2362 POJ 1011(搜索+剪枝) POJ 1416 POJ 2676 POJ 1129:white_question_...
北大POJ3087-Shuffle'm Up 解题报告+AC代码
北大POJ3026-Borg Maze【BFS+Prim】 解题报告+AC代码
北大POJ初级-所有题目AC代码+解题报告
北大POJ1159-Palindrome 解题报告+AC代码
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
很好很强大的POJ分类 新手+进阶+题目完全分类 赶快下载