L. Bridge Renovation
题目大意:现需18,21,25的木板n块,问你最少需要多少块60的木板来满足需求,木板只能裁不能拼
#1 尽可能的利用每一块木板
#2 如何利用好每块木板?
思路:由于18*2+21< 60,21*2 + 18 <= 60,所以可用三块木板裁出3快18的和21的,如果余2,可以用2块木板凑出2*21 + 18,和18 + 25, 若剩一块就正常裁,剩下25的就正常裁
代码:
void solve()
{
int n; cin >> n;
int res = n / 3 * 2;
int m = n % 3;
if (m == 1)
{
res ++ ;
}
else if (m == 2)
{
res += 2;
n -- ;
}
res += (n + 1) / 2;
cout<<res<<endl;
}
C. Action Figures
题目大意:给你一串字符串,刚开始你有最大代价,定义每个字符的代价大小等于其下标,下标从1开始,当字符为1时,你能从其前面选择一个没被用过的字符,使这两个字符的总代价为较小的那个,求最小代价
#1 尽量洗掉代价较大的1
#2 对于每个1,先后前面的0洗,实在没有再和前面的1洗
思路:开一个deque存1的坐标,vec存0的坐标,每次取后面1,每次先用接近1的0,没0用就用前面的1,洗掉该1的代价
代码:
void solve()
{
int n;
cin >> n;
string s; cin >> s;
deque<int> q;
i64 res = 0;
vector<int> v;
for (int i = 0; i < s.size(); i ++ )
{
res += i + 1;
if (s[i] == '1') q.push_back(i+1);
else v.push_back(i+1);
}
while (q.size())
{
int x = q.back(); q.pop_back();
while (v.size() && v.back() > x) v.pop_back();
if (v.size())
{
v.pop_back();
res -= x;
}
else
{
if (q.size())
{
q.pop_front();
res -= x;
}
}
}
cout<<res<<endl;
}
B. Binomial Coefficients, Kind Of
题目大意:给你公式与别的量,叫你求每个结果
#1 打表找规律
思路:打表发现,k不为0且不与n相等的情况,值为2的k次方,递推预处理即可
代码:
LL qmi(int a,int b,int p)
{
LL ans=1%p;
while(b)
{
if(b&1) ans=ans*a%p;
a=a*(LL)a%p;
b/=2;
}
return ans;
}
void solve()
{
int m; cin >> m;
vector<array<int,2>> v(m);
for (int i = 0; i < m; i ++ ) cin >> v[i][0];
for (int i = 0; i < m; i ++ ) cin >> v[i][1];
for (int i = 0; i < m; i ++ )
{
if (v[i][1] == 0)
{
cout<<1<<endl;
}
else if (v[i][0] == v[i][1])
{
cout<<1<<endl;
}
else
{
cout<<qmi(2,v[i][1],M)<<endl;
}
}
}
A. Two Screens
题目大意:给你两种代价为1的操作,用最少的代价得到给定的2个字符串
思路:求字符串前缀,没什么好说的
代码:
void solve()
{
string s1,s2; cin >> s1 >> s2;
int len = 0;
for (int i = 1; i <= min(s1.size(), s2.size()); i ++ )
{
if (s1.substr(0,i) != s2.substr(0,i)) break;
len = i;
}
if (len == 0) cout<<s1.size() + s2.size()<<endl;
else
cout<<1+s1.size()+s2.size()-len<<endl;
}