今天写了三个题
1parket
这题一开始写想的是排列组合,但其实是子集问题,只得了48分,后面看了题解,只要对当前数放与不放就可以得到所有子集
放下代码
#include<iostream>
#include<algorithm>
using namespace std;
struct parket
{
int si,bi;
}a[100];//存放每个物品的酸度和苦度
int sums=1,sumb;//酸度的积,苦度的和
int n;
int minn=99999999;//最小解
void dfs(int i,int sums,int sumb)
{
if(i>=n)//到达临界点
{
if(minn>abs(sums-sumb))minn=abs(sums-sumb);//求最小解
return;
}
dfs(i+1,sums*a[i].si,sumb+a[i].bi);//放
dfs(i+1,sums,sumb);//不放
}
int main()
{
cin >> n;
for(int i=0;i<n;i++)
{
cin>>a[i].si>>a[i].bi;
}
if(n>=2)
{
dfs(0,1,0);
}
else minn=abs(a[0].si-a[0].bi);
cout << minn;
}
2考前抱佛脚
这题有点动态规划的意思,左右脑,在dfs中对当前数是放在左脑还是右脑进行了两次搜素与上面那道parket类似,这题要注意是对每科进行dfs一次,所以每次dfs后要对左右脑和解赋初值下面放代码
#include<iostream>
#include<algorithm>
using namespace std;
int a[4][21];//每科题目列表
int s[4];//每科的题目
int minn;//每科最小时长
int lef=0;//左右脑
int righ=0;
void dfs(int x,int y)
{
if(y>=(s[x]))//到达这科最大题目个数
{
minn=(min(minn,max(lef,righ)));//求出搜到结果的最小值
return;
}
lef+=a[x][y];
dfs(x,y+1);
lef-=a[x][y];//回溯
righ+=a[x][y];
dfs(x,y+1);
righ-=a[x][y];
}
int main()
{
int ans=0;
for(int i=0;i<4;i++)
cin>>s[i];
for(int i=0;i<4;i++)
{
for(int j=0;j<s[i];j++)
{
cin >>a[i][j];
}
}
for(int i=0;i<4;i++)
{
lef=0;
righ=0;//每次dfs完赋初值
minn=9999999;
dfs(i,0);
ans+=minn;
}
cout << ans;
}
3迷宫
最简单的的搜索题
#include <iostream>
using namespace std;
int mx,my,t;//地图大小,t代表障碍数
int cx,cy;//出口
int kx,ky;//起点
int ans=0;
int a[50][50],book[50][50];
void dfs(int x,int y,int step)
{
int next[4][2]={
{0,1},{1,0},{0,-1},{-1,0}//方向
};
int tx,ty,k;
if(x==cx&&y==cy)//出口,当找到
{
ans++;//解决方案加1
return;
}
for(int k=0;k<4;k++)//循环该位置上下左右
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<1||tx>mx||ty<1||ty>my)//位置出界
continue;//找下个位置
if(a[tx][ty]==0&&book[tx][ty]==0)//该位置没有障碍物且没走过
{
book[tx][ty]=1;//标记已经走过
dfs(tx,ty,step+1);//走下一步
book[tx][ty]=0;//标记清除
}
}
return;
}
int main()
{
cin >> mx>>my>>t;
cin >> kx>>ky>>cx>>cy;
while(t--)
{
int x,y;
cin >>x>>y;
a[x][y]=1;
}
book[kx][ky]=1;
dfs(kx,ky,0);
cout << ans;
}