2022.1.25
T1:走迷宫
可以写if,也可以用for循环配合二维数组
注意初始化 vis[1][1]=1
注意递归次数过多会导致MLE(奇怪的知识又增加了)
点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdlib>
using namespace std;
int n,a[110][110],ans;
int b[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
bool vis[110][110];
void dfs(int x,int y,int t)
{
for(int i=0;i<8;i++)//算符种类
{
if((!vis[x+b[i][0]][y+b[i][1]])&&(!a[x+b[i][0]][y+b[i][1]))//判重
if(x+b[i][0]>=1&&x+b[i][0]<=n)
if(y+b[i][1]>=1&&y+b[i][1]<=n)//边界 合法
{
x+=b[i][0];
y+=b[i][1];
vis[x][y]=1;
if(x==1&&y==n)ans++;
else dfs(x,y,t+1);
vis[x][y]=0;
x-=b[i][0];
y-=b[i][1];
}
}
}
int main()
{
vis[1][1]=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
dfs(1,1,1);
printf("%d",ans);
return 0;
}
T2:团结地入伍
很像监狱那道题,几乎一样:先标记再判断,分选与不选两种情况
至于没一次AC?T1MLE阴影过深,数组只开到了30(居然也过了67分)
像在洛谷上水一波结果T掉了一个????
点击查看代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdlib>
using namespace std;
int book[110][110],n,m,a[110],vis;
int x[110],ans,ans1;//x作为a的过程,ans1作为ans的过程
void dfs(int k)
{
if(k>n)//边界
{
if(ans1<=ans)return;//剪枝
else ans=ans1;
for(int i=1;i<=n;i++)
{
a[i]=x[i];
}
return;
}
vis=1;//选
for(int i=1;i<k;i++)//不算自己
if(book[i][k]&&x[i])
{
vis=0;
break;//优化在这里
}
if(vis)
{
x[k]=1;
ans1++;
dfs(k+1);//
ans1--;
x[k]=0;
}
dfs(k+1);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
book[u][v]=1;
book[v][u]=1;
}
dfs(1);
printf("%d\n",ans);
for(int i=1;i<=n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
T3:最佳调度
果然带调度的题都很恶心。。。
三个优化一个不能少
- 若和已经大于minn剪掉y>=minn要带等
- 只有和加上后还小于才继续
- 主程序里要sort一次,目的是尽可能考前地剪掉和大的情况
点击查看代码
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
using namespace std;
int a[10010],m[10010],n,k,minn=1e6;
bool cmp(int aa,int bb){ return aa>bb; }
void dfs(int x,int y)
{
if(y>=minn)return;
if(x>n)
{
minn=min(y,minn);
return;
}
for(int i=1;i<=k;i++)
{
if(m[i]+a[x]<=minn&&x<=n)
{
m[i]+=a[x];
y=max(y,m[i]);
dfs(x+1,y);
m[i]-=a[x];
}
}
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
dfs(1,0);
printf("%d",minn);
return 0;
}
T4:图的m着色问题
调的时候要注意前后一制,一开始写x++;后来改为for(int i=1;i<=n;i++)后要记得改回来
点击查看代码
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,k,ans,col[10010],e[110][110];
bool judge(int k,int i)
{
for(int j=1;j<k;j++)
{
if(e[j][k]==1&&col[j]==i)return false;
}
return true;
}
void search(int k,int x)
{
if(k>n)ans++;
else for(int i=1;i<=x;i++)
{
if(judge(k,i))
{
col[k]=i;;
search(k+1,x);
}
}
}
int main()
{
scanf("%d%d%d",&n,&k,&m);
for(int i=1;i<=k;i++)
{
int u,v;
scanf("%d%d",&u,&v);
e[u][v]=1;
e[v][u]=1;
}
search(1,m);
printf("%d",ans);
return 0;
}