第一题:
题意:有两种颜色的砖块,红色和蓝色。给你两种砖块的高度和数量,要求砖块只能放在与其不同颜色的砖块上面。问一共可以叠出多少种高度。
题解:暴力枚举。
代码:
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
set<int> s;
void dfs(int rc,int rh,int bc,int bh,int high,int color)
{
if(color==0&&rc>0)
{
s.insert(high+rh);
dfs(rc-1,rh,bc,bh,high+rh,1);
}
else if(color==1&&bc>0)
{
s.insert(high+bh);
dfs(rc,rh,bc-1,bh,high+bh,0);
}
}
class TheBrickTowerEasyDivTwo {
public:
int find(int redCount, int redHeight, int blueCount, int blueHeight) {
s.clear();
dfs(redCount,redHeight,blueCount,blueHeight,0,0);
dfs(redCount,redHeight,blueCount,blueHeight,0,1);
return s.size();
}
};
第二题:
题意:有n个不同高度的砖块排成一列,要求两块砖块之间的距离不小于两者中最大的高度,让你重新给砖块排序,使得第1块到最后1块之间的距离最小。距离相同输出字典序最小的。
题解:求出全排列然后计算距离,保留最小值。ps:求全排列可以用STL
代码:
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
vector<int> num,temp;
int check()
{
int summ=0;
int len=num.size();
for(int i=1;i<len;++i)
summ+=max(temp[num[i]],temp[num[i-1]]);
return summ;
}
class TheBrickTowerMediumDivTwo {
public:
vector <int> find(vector <int> heights) {
vector<int> ans;
ans.clear();
num.clear();
temp.clear();
int len=heights.size();
if(len==1)
{
ans.push_back(0);
return ans;
}
for(int i=0;i<len;++i)
{
num.push_back(i);
temp.push_back(heights[i]);
}
int minn=99999;
do
{
int m=check();
if(m<minn)
{
ans.clear();
for(int i=0;i<len;++i) ans.push_back(num[i]);
minn=m;
}
}while(next_permutation(num.begin(),num.end()));
return ans;
}
};
第三题:
题意:给你最多C(1<=C<=4)种颜色的砖块,每种砖块有无限个(1*1*1的立方体),问用砖块拼成一个2*2*h(h<=H)的长方体,并且相邻两块单位立方体颜色相同的对数小于等于K的总方案数是多少。
题解:dp[h][i][j][k][l][x]表示高度h,最上面的面的四个立方体的颜色(i,j,k,l),总共的相邻的不同颜色对数为x。之后就是状态的递推了。
代码:
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
#define LL long long
#define mod 1234567891
LL dp[55][5][5][5][5][10];//dp[h][i][j][k][l][x]表示高度h,最上面的面的四个立方体的颜色(i,j,k,l),总共的颜色对数为x
class TheBrickTowerHardDivTwo {
public:
int find(int C, int K, int H) {
int temp;
memset(dp,0,sizeof(dp));
for(int i=0;i<C;++i)
for(int j=0;j<C;++j)
for(int k=0;k<C;++k)
for(int l=0;l<C;++l)
{
temp=((i==j)+(j==l)+(l==k)+(k==i));
if(temp<=K) dp[1][i][j][k][l][temp]=1;
}
for(int h=2;h<=H;++h)
for(int x=0;x<=K;++x)
for(int i=0;i<C;++i)
for(int j=0;j<C;++j)
for(int k=0;k<C;++k)
for(int l=0;l<C;++l)
for(int a=0;a<C;++a)
for(int b=0;b<C;++b)
for(int c=0;c<C;++c)
for(int d=0;d<C;++d)
{
temp=((i==j)+(i==k)+(k==l)+(l==j)+(a==i)+(b==j)+(c==k)+(d==l));
if((dp[h-1][a][b][c][d][x])&&(x+temp<=K))
dp[h][i][j][k][l][x+temp]=(dp[h][i][j][k][l][x+temp]+dp[h-1][a][b][c][d][x])%mod;
}
LL ans=0;
for(int h=1;h<=H;++h)
for(int x=0;x<=K;++x)
for(int i=0;i<C;++i)
for(int j=0;j<C;++j)
for(int k=0;k<C;++k)
for(int l=0;l<C;++l)
ans=(ans+dp[h][i][j][k][l][x])%mod;
return (int)ans;
}
};