蓝桥杯每日一题
1.木棒
2.n-皇后问题
Acwing算法基础课
1.子集生成
以下是部分题目的代码
//木棒
int a[70], n;
int init_len, maxn, sum;//分别记录要拼成的长度,遍历上界和下界
bool st[70];
bool dfs(int u, int part, int cur)//第u组,part第u组的已有长度,cur表示第u组的枚举位置;
{
if (u * init_len == sum) return true;//注意是init_len
if (part == init_len) return dfs(u + 1, 0, 1);
for (int i = cur; i <= n; i++)
{
if (part + a[i] > init_len) continue;//超过假设长度就选下一根,因为下一根更短
if (st[i] == true) continue;
st[i] = true;
if (dfs(u, part + a[i], i + 1)) return true;
st[i] = false;//假设选了这根后,上面的if语句不执行,那就不选这根
//较难理解的地方,//如果第一根失败了或者最后一根失败了,就一定失败
//大佬的讲解:
//因为加上它之后长度为length,所以他就是第u层的最后一根木棍。
//第u层最后一根木棍拼好之后,会继续拼下面的层数的木棒。
//如果下面的层数都能拼好,也就是所以木棍不重不漏的拼成了木棒,第u层会返回给u - 1层true,而u - 1层的return dfs(u + 1, 0, 0); 会继续将true返回给u - 2层,就这样一直返回下去直到主函数里。
//一旦下面出现了一层凑不出木棒的(上一层能凑出)就会返回false给上一层。返回给上一层之后会先传递到上一层最后一根木棍,而这根木棍满足part + w[i] == length,但是由于前面判断语句if(dfs(u, w[i] + part, i + 1))不成立,会继续往下走,遇到if(!part || w[i] + part == length) return false; 后返回false
//我的理解是:
//第i根木棍被当成当前层的第一根都不行,那么在下一层中也必定不行
//a[i] + part == init_len 是为了将下一层函数的false快速传递给当前层
if (!part || a[i] + part == init_len) return false;
//跳过相同的木棍,这一根不行,下一根长度相同的木棍也必定不行
int j = i;
while (j <= n && a[i] == a[j]) j++;
i = j - 1;
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
while (cin >> n && n)
{
memset(st, false, sizeof st);
maxn = 0, sum = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
maxn = max(maxn, a[i]);
sum += a[i];
}
sort(a + 1, a + 1 + n, [&](int x,int y) {
return x > y;
});
for (int i = maxn; i <= sum; i++)
{
if (sum % i != 0) continue;//显然不符合条件
init_len = i;
if (dfs(0, 0, 1))
{
cout << i << endl;
break;
}
}
}
return 0;
}