解题思路:直接通过暴力模拟每次装包的状态,即可
注意事项:装包的时候一定记住要从大到小的顺序来包装,否则会出现WA
参考代码:
#include<iostream>//包装从大到小包装,并且每次判断空间就OK #include<vector>//暴力方法,直接模拟装包 #include<cstring> #include<algorithm> using namespace std; vector<int> item;//候选的东西 当前空间被占用为-1 否则为0 int pak[6][6]={0};//包裹地图,用于判断到底当前物品是否有空间 bool check(int a,int b,int c,int d,int e,int f)//用于判断当前输入的值是否全为0 { if(a||b||c||d||e||f) return true; else return false; } bool judge(vector<int> item)//判断item数组里还有没有没有装进去的物品 { for(int i=0;i<item.size();i++) { if(item[i]!=-1) return true;//-1代表已经被装进去了 如果有不是-1的数代表还有没有装的数 } return false; } bool find(int x,int &i,int &j)//判断当前背包中是否能装进item[i] { bool flag=true; if(x==5)//一开始用循环暴力搜索TLE了 直接判断5*5的空间有没有空间 i,j是代表以i,j为起始点的5*5空间 在6*6的背包中只能有4个起始点 [0,0] [0.1] [1,0] [1,1] { for(i=0;i<2;i++) { for(j=0;j<2;j++) { if(pak[i][j]==0&&pak[i][j+1]==0&&pak[i][j+2]==0&&pak[i][j+3]==0&&pak[i][j+4]==0&&pak[i+1][j]==0&&pak[i+1][j+1]==0&&pak[i+1][j+2]==0&&pak[i+1][j+3]==0&&pak[i+1][j+4]==0&&pak[i+2][j]==0&&pak[i+2][j+1]==0&&pak[i+2][j+2]==0&&pak[i+2][j+3]==0&&pak[i+2][j+4]==0&&pak[i+3][j]==0&&pak[i+3][j+1]==0&&pak[i+3][j+2]==0&&pak[i+3][j+3]==0&&pak[i+3][j+4]==0&&pak[i+4][j]==0&&pak[i+4][j+1]==0&&pak[i+4][j+2]==0&&pak[i+4][j+3]==0&&pak[i+4][j+4]==0) return true; } } return false; } else if(x==4)//与上述判断方式一样 { for(i=0;i<3;i++) { for(j=0;j<3;j++) { if(pak[i][j]==0&&pak[i][j+1]==0&&pak[i][j+2]==0&&pak[i][j+3]==0&&pak[i+1][j]==0&&pak[i+1][j+1]==0&&pak[i+1][j+2]==0&&pak[i+1][j+3]==0&&pak[i+2][j]==0&&pak[i+2][j+1]==0&&pak[i+2][j+2]==0&&pak[i+2][j+3]==0&&pak[i+3][j]==0&&pak[i+3][j+1]==0&&pak[i+3][j+2]==0&&pak[i+3][j+3]==0) return true; } } return false; } else if(x==3) { for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(pak[i][j]==0&&pak[i][j+1]==0&&pak[i][j+2]==0&&pak[i+1][j]==0&&pak[i+1][j+1]==0&&pak[i+1][j+2]==0&&pak[i+2][j]==0&&pak[i+2][j+1]==0&&pak[i+2][j+2]==0) return true; } } return false; } else if(x==2) { for(i=0;i<5;i++) { for(j=0;j<5;j++) { if(pak[i][j]==0&&pak[i][j+1]==0&&pak[i+1][j]==0&&pak[i+1][j+1]==0) return true; } } if(flag==false) return false; } else if(x==1)//等于1*1的时候直接判断[i,j]是否为空即可 { for(i=0;i<6;i++) { for(j=0;j<6;j++) { if(pak[i][j]==0) return true; } } return false; } else//判断6*6的直接背包空间遍历即可 若有点被占用,直接说明装不下 { for(i=0;i<6;i++) { for(j=0;j<6;j++) { if(pak[i][j]==-1) return false; } } i=0;j=0; return true; } } void alert(int t,int x,int y)//改变包裹空间状态的函数,即以x,y为顶点,边长为x的物品装进包裹,被占用的空间设置-1即可 { int cnt_x=0;int cnt_y=0; for(int i=x;cnt_x<t;i++) { cnt_y=0; for(int j=y;cnt_y<t;j++) { pak[i][j]=-1; cnt_y++; } cnt_x++; } return; } int main() { int x1=-1,x2=-1,x3=-1,x4=-1,x5=-1,x6=-1; while(check(x1,x2,x3,x4,x5,x6)) { int cnt=0; cin>>x1>>x2>>x3>>x4>>x5>>x6; for(int i=0;i<x1;i++) item.push_back(1); for(int i=0;i<x2;i++) item.push_back(2); for(int i=0;i<x3;i++) item.push_back(3); for(int i=0;i<x4;i++) item.push_back(4); for(int i=0;i<x5;i++) item.push_back(5); for(int i=0;i<x6;i++) item.push_back(6);//数据的初始化,将待装的物品放入item数组 sort(item.begin(),item.end()); reverse(item.begin(),item.end());//这里将item里面的东西按照从大到小的顺序排列,保证每次优先装大的物品 //for(int i=0;i<item.size();i++) cout<<item[i]; while(judge(item))//当还有物品时 继续装 { int i=0;int x=0;int y=0;//用i来遍历item的物品 x,y是搜索指针,代表以i,j为顶点的正方形的空间是空的 while(i<item.size()) { if(item[i]!=-1&&find(item[i],x,y))//如果当前item中有物品并且能找到空间 { alert(item[i],x,y);//装进去 item[i]=-1;//装完了别忘记设置-1 } i++; //遍历下一个物品 x=0;y=0;//初始化指针,默认从[0,0]搜索 } cnt++;//如果当前遍历完了item,说明要么item空了,要么包裹满了 直接将答案cnt++ memset(pak,0,sizeof(pak));//新的背包初始化 } if(check(x1,x2,x3,x4,x5,x6))cout<<cnt<<endl;//若每一行输入的数不是全为0,输出答案 item.clear(); } return 0; }
0.0分
2 人评分
A+B for Input-Output Practice (II) (C语言代码)浏览:1043 |
DNA (C语言描述,蓝桥杯)浏览:1653 |
1908题解浏览:680 |
C语言程序设计教程(第三版)课后习题9.8 (C语言代码)浏览:702 |
文科生的悲哀 (C语言代码)浏览:1538 |
图形输出 (C语言代码)浏览:1422 |
杨辉三角 (C语言代码)浏览:504 |
计算质因子 (C语言代码)浏览:778 |
A+B for Input-Output Practice (I) (C语言代码)浏览:451 |
C语言程序设计教程(第三版)课后习题1.5 (C语言代码)浏览:559 |