闲话 11.2
也是打上搜了。
小木棍
曾经在题库上做过,数据水就过了,交洛谷发现只有 87pts。
《剪 枝 盛 宴》
- 钦定长度:最小肯定是最长的那根木棍,最长肯定是所有木棍的总和,并且这个长度一定只能是总和的因数。
- 选择顺序:如果选一个长的合法,那么选若干个和相同的短的一定合法但不优,因此按长度倒序排序。
- 如果合法立即回溯。
- 回溯后立即撤销标记,省略 memset。
- 每次拼接只会取长度不比上一次选择的木棍长的木棍,可以二分找。
- 如果某一根木棍不合法,与其长度相同的所有其他木棍均不合法。
- 如果某根小木棍与当前拼接刚好为钦定长度但不合法,此后一定不会出现合法方案,直接回溯。
点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{
char ch = getchar(); lx x = 0, f = 1;
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
return x * f;
}
#undef lx
#define qr qr()
#define fi first
#define se second
#define pii pair<int, int>
#define P_B(x) push_back(x)
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 100 + 5;
const int mod = 998244353;
int n, sum, ans;
int a[N];
bool yz[N], ok;
namespace Wisadel
{
void Wdfs(int nlen, int nok, int ned, int id)
{
if(nlen == ned)
{
if(nok == sum / ned){ok = 1; return ;}
fo(i, 1, n) if(!yz[i])
{
yz[i] = 1;
Wdfs(a[i], nok + 1, ned, i);
yz[i] = 0;
if(ok) return ;
break;
}
return ;
}
int l = id + 1, r = n;
while(l < r)
{
int mid = (l + r) >> 1;
if(a[mid] <= ned - nlen) r = mid;
else l = mid + 1;
}
int zc = 0;
fo(i, l, n) if(!yz[i] && a[i] != zc)
{
yz[i] = 1;
Wdfs(nlen + a[i], nok, ned, i);
yz[i] = 0;
if(ok) return ;
if(nlen + a[i] == ned) return ;
zc = a[i];
}
}
short main()
{
// freopen(".in", "r", stdin), freopen(".out", "w", stdout);
n = qr;
fo(i, 1, n) a[i] = qr, sum += a[i];
ans = sum;
sort(a + 1, a + 1 + n, [](int a, int b){return a > b;});
fo(i, a[1], sum) if(sum % i == 0)
{
yz[1] = 1;
Wdfs(a[1], 1, i, 1);
yz[1] = 0;
if(ok){ans = i; break;}
}
printf("%d\n", ans);
return Ratio;
}
}
signed main(){return Wisadel::main();}
买瓜
💧
\(n\le 30\),一个瓜只有三种可能,暴力枚举 \(\mathcal{O(3^n)}\) 显然过不了,但是这是搜索题,所以重点还是在于各种小剪枝。
来!
- R1:和木棍同理,先拿重的比较优。
- R2:显然拿之后超过目标重量的不能拿。
- R3:显然当前次数超过目前最优答案就不用再考虑了。
然后,
噗叽啪
🤔?。。。🤓!。。。🤫
- R4:有没有什么一进去就知道这样做没前途的剪枝呢?诶,如果后面的瓜全加上都达不到目标重量显然是无解的,记录后缀和即可。
🧘👍
点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{
char ch = getchar(); lx x = 0, f = 1;
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
return x * f;
}
#undef lx
#define qr qr()
#define fi first
#define se second
#define pii pair<int, int>
#define P_B(x) push_back(x)
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 100 + 5;
const int mod = 998244353;
int n, m, ans = 1e9;
int a[N];
ll hz[N];
namespace Wisadel
{
void Wdfs(int now, double tot, int tim)
{
if(tim >= ans) return ;
if(tot == 1.0 * m)
{
ans = min(ans, tim);
return ;
}
if(now > n || tot + 1.0 * hz[now] < 1.0 * m) return ;
if(a[now] + tot <= 1.0 * m) Wdfs(now + 1, tot + 1.0 * a[now], tim);
if((1.0 * a[now]) / 2 + tot <= 1.0 * m) Wdfs(now + 1, tot + (1.0 * a[now]) / 2, tim + 1);
Wdfs(now + 1, tot, tim);
}
short main()
{
// freopen(".in", "r", stdin), freopen(".out", "w", stdout);
n = qr, m = qr;
fo(i, 1, n) a[i] = qr;
sort(a + 1, a + 1 + n, [](int a, int b){return a > b;});
fu(i, n, 1) hz[i] = hz[i + 1] + a[i];
Wdfs(1, 0, 0);
printf("%d\n", ans == 1e9 ? -1 : ans);
return Ratio;
}
}
signed main(){return Wisadel::main();}
Expression
诶,\(a+b=c\),这个我会🤓。
🤔?
考虑怎么入手这道题,首先比较明显的,我们必须保证 \(a+b=c\)。考虑逐位运算,从低到高,发现每一位上我们之多加一个数就一定能让该位运算合法,因此每一位还是只有三种可能。
考虑什么时候进位,显然,当 \(a+b\equiv c\pmod {10}\) 时这一位上合法,那么我们可以进位。
考虑什么时候结束,当 \(a=b=c=jinwei=0\) 时,即所有位都考虑完了,显然求解结束。
比较特殊一点,当 \(c=0\) 时,此时显然我们只需要在 \(c\) 上补充,单独考虑即可,本质上是一个小剪枝。
然后就做完了,温馨提示:直接这么写 scanf("%lld+%lld=%lld", &a, &b, &c)
就能很方便地快速输入,不需要用到 string 什么的。
点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{
char ch = getchar(); lx x = 0, f = 1;
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
return x * f;
}
#undef lx
#define qr qr()
#define fi first
#define se second
#define pii pair<int, int>
#define P_B(x) push_back(x)
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 100 + 5;
const int mod = 998244353;
ll a, b, c, ans = 1e9;
ll aaa, bbb, ccc;
namespace Wisadel
{
void Wdfs(ll a, ll b, ll c, ll jin, ll aa, ll bb, ll cc, int now, ll bas)
{
if(now >= ans) return ;
if(!a && !b && !c && !jin)
{
ans = now, aaa = aa, bbb = bb, ccc = cc;
return ;
}
if(!c)
{
ll res = a + b + jin;
int zc = 0;
while(res) zc++, res /= 10;
Wdfs(0, 0, 0, 0, aa + bas * a, bb + bas * b, cc + bas * (a + b + jin), now + zc, bas * 10);
return ;
}
if((a + b + jin) % 10 == c % 10)
{
Wdfs(a / 10, b / 10, c / 10, (a % 10 + b % 10 + jin) / 10, aa + bas * (a % 10), bb + bas * (b % 10), cc + bas * (c % 10), now, bas * 10);
return ;
}
Wdfs(a * 10 + (c % 10 - b % 10 - jin + 10) % 10, b, c, jin, aa, bb, cc, now + 1, bas);
Wdfs(a, b * 10 + (c % 10 - a % 10 - jin + 10) % 10, c, jin, aa, bb, cc, now + 1, bas);
Wdfs(a, b, c * 10 + (a % 10 + b % 10 + jin) % 10, jin, aa, bb, cc, now + 1, bas);
}
short main()
{
// freopen(".in", "r", stdin), freopen(".out", "w", stdout);
scanf("%lld+%lld=%lld", &a, &b, &c);
Wdfs(a, b, c, 0, 0, 0, 0, 0, 1);
printf("%lld+%lld=%lld\n", aaa, bbb, ccc);
return Ratio;
}
}
signed main(){return Wisadel::main();}
锣鼓月赛 T3 打不动了,遂来写闲话抽卡记录。
体活,打了会羽毛球就回宿舍了,泡上面后开始打电话赛博抽卡。
Ratio:你看要是拉开有火就是出了
我妈:诶这个好像就有火
😎😎😎
我妈:(念了一连串四星之后)这个是六星
Ratio:是不是六个字的
我妈:叫什么拉普兰德?
😋😋😋
Ratio:接着抽
我妈:这个又有火?🧐?怎么没六星
原来第一发是镀彩
Ratio:(科普了一下火和金)😬😬😬再来一发
我妈:诶这个又跟刚才一样
Ratio:😖😖😖那直接右上角跳过吧
我妈:那个“skip”是吧。。。?诶有个六星
Ratio:!!!😆😆😆是不是金色头发的😋😋😋叫什么?
我妈:头发好像是浅白色的,,等会我截图了,确实有点黄。。。
😆😆😆
最后口述查看干员位置的方法确认了就是忍冬,30 发毕业,爽🤤🤤🤤
不过连着两发镀彩是不是过于小概率了
偷偷塞一个干员数值
未完待续
上一个未完的是不是还在待续呢🤔