搜索

华容道70
设两个变量,记在一个结构体里
在进行爆搜,就是一个普通的bfs,只会简单的爆搜,正解是,三个bfs,先处理出白板到起始的最短距离,在处理出移动的代价,在跑一边最短路;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
using namespace std;

int n,m,k;
struct stu{
int x,y,x1,y1,s;
};
int f[31][31][31][31];
int x[4]={
1,-1,0,0};
int y[4]={
0,0,1,-1};
int a[39][39];
int bfs(stu p,int x2,int y2)
{
queue<stu> q;
q.push(p);
memset(f,0,sizeof(f));
f[p.x][p.y][p.x1][p.y1]=1;
while(!q.empty())
{
stu o=q.front();q.pop();
if(o.x1==x2&&o.y1==y2)
return o.s;
for(int i=0;i<=3;i++)
{
stu tmp;
tmp.x=o.x+x[i];
tmp.y=o.y+y[i];
if(o.x1==tmp.x&&o.y1==tmp.y)
{
tmp.x1=o.x;
tmp.y1=o.y;
}
else
{
tmp.x1=o.x1;
tmp.y1=o.y1;
}
tmp.s=o.s+1;
if(tmp.x<1||tmp.y<1||tmp.x>n||tmp.y>m||!a[tmp.x][tmp.y]) continue;
if(!f[tmp.x][tmp.y][tmp.x1][tmp.y1])
{
q.push(tmp);
f[tmp.x][tmp.y][tmp.x1][tmp.y1]=1;
}
}

}
return -1;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);

for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);

for(int i=1;i<=k;i++)
{
stu p;int x2,y2;
scanf("%d%d%d%d%d%d",&p.x,&p.y,&p.x1,&p.y1,&x2,&y2);
p.s=0;
printf("%d\n",bfs(p,x2,y2));
}
}

生日蛋糕
这里写图片描述
进行dfs
起始条件为最大的半径和高,枚举他们,再加一系列剪枝
1.如果当时的面积大于最优解,返回
2.如果所有的体积加起来都不够v,返回
3.如果加上最小的体积都比v大,返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
int v,m,ans=0x7fffffff,s[29999],max1[99][99][99];
void dfs(int h,int r,int V,int S,int p)
{

if(S>=ans)return ;

if(p==m)
{
if(V==0)
ans=min(S,ans);
return ;
}

if(V>max1[p][r][h]) return ;
for(int j=r-1;j>=m-p;j--)
for(int i=min(h-1,V/(j*j));i>=m-p;i--)
dfs(i,j,V-j*j*i,S+2*i*j,p+1);
}
int main()
{
scanf("%d%d",&v,&m);
for(int i=m;i>=1;i--)
s[i]=s[i+1]+i*i*i;
for(int i=1;i<=sqrt(v);i++)
for(int j=1;j<=v/(i*i);j++){

for(int k=m-1;k>=1;k--)
{
max1[k][i][j]=max1[k+1][i][j]+(i-m+k)*(i-m+k)*(j-m+k);
}
}
for(int i=m;i<=sqrt(double(v/m));i++)
for(int j=m;j<=v/(m*m);j++)
dfs(j,i,v-i*i*j,2*i*j+i*i,1);
int t=0x7fffffff;
if(ans!=t) printf("%d",ans);
else printf("0");
}
最近的文章

摄像头

拓补排序找入度为零的,就是没被监视的,删掉继续找入度为零的,继续删直到找不到输出答案 1234567891011121314151617181920212223242526272829303132333435363738394041#include&lt;cstdio&gt;#include&lt; …

于  拓补排序 继续阅读
更早的文章

day4

alien飞船降落问题矩阵前缀和+枚举求出前缀和,暴力枚举每一个子矩阵的和,是0就可以降落注意有正方形飞船,长度不等于点123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495 …

于  2016~2017 继续阅读