1985E
看完题目之后 , 第一想法是最暴力的On3 , 对于每个i ,j ,k , 如果它们符合k的体积的话,我们就可以把这个长方体一格一格的移动 , 对于x方向 , 我们一共能移动a - i次 , 那么也就有a -i+1种方法放置 , y轴和z轴也是同理。
当我们信心满满的交上去之后, 就会发现TLE了 , 那么我们可以优化一下On3的算法 , 优化成On2 ,枚举i j , 如果满足 k %(i *j) == 0的话 , 就可以得到k。
void solve(){
//在n里面选择 x种连续的方式
//n - x + 1
int ans = 0;
cin>>a>>b>>c>>k;
int r =0;
for(int i =1;i<=a;++i){
for(int j =1;j<=b;++j){
if(k % (i *j) == 0){
r = k /(i*j);
int xx = a - i+1;
int yy = b - j+1;
int zz = c - r +1;
ans = max(ans , xx*yy*zz);
}
}
}
cout<<ans<<endl;
}
1984C1
这题可以用dp 或者贪心的思路来解
当c+ai是正数时 , 方案1 和 2是没有区别的 , 但是当c+ai是负数的时候 , 就不一样了,当它是负数时,此时小于0,讲道理我们应该启动2了 , 但是我们不知道后面的数会不会也是负数 , 这样它加完后面的数字就会更小了 , 但是绝对值也会对应的更大了。
所以我们可以记录一下它在遍历时的最小值 ,如果最小值小于0 , 我们就把答案 加上它的两倍
void solve(){
cin>>n;
for(int i =1;i<=n;++i)cin>>a[i];
int ans = 0 , mi = INF;
for(int i =1;i<=n;++i){
ans +=a[i];
mi = min(mi , ans);
}
if(mi >=0){
cout<<ans<<endl;
return;
}
else {
cout<<ans - 2*mi<<endl;
}
}
1981B
这是某场div2的B题 , 难度大概在1400
首先 , 我们的所有元素每秒都会跟相邻的元素按位或
对于第i个元素来说
第一秒 : ai-1 | ai | ai+1
由于ai-1 和 ai+1 也在变化 第二秒 : ai-2 | ai-1 | ai | ai | ai | ai+1 | ai+2 = ai-2 | ai-1 | ai | ai+1 | ai+2
那么我们可以找到规律 ,在第x秒 , ai的变化为 : ai-x | ..... | ai | ... | ai+x
考虑到边界情况有0的存在 最左边的数为 max(0 , ai-x)
我们就有如下代码
void solve(){
cin>>n>>m;
l = max(0ll ,n-m);
r = n+m;
int ans = 0;
//从n-m 到n+m 遍历到答案
for(int i =l;i<=r;++i){
ans =ans | i;
}
cout<<ans;
}
但是这个交上去会发现超时了。那么就引入接下来的一个技巧, 叫快速或和
int ksh(int l ,int r){
while(l <r){
l |= (l+1);
}
return l;
}
完整代码
int hsum(int l ,int r){
while(r > l){
l |=(l+1);
}
return l;
}
void solve(){
cin>>n>>m;
l = max(0ll , n-m);
r = n+m;
//从 n-m 或到n+m
cout<<hsum(l , r)<<endl;
}
1980D
我们可以用b数组把gcd的这个先给表示出来 ,遍历b数组 , 如果遇到bi > bi+1的这种情况 ,我们可以考虑删掉第bi个点 , bi-1个点 ,bi+1个点
首先在i之前的所有数字肯定是没有问题的 , 主要就是bi-1 bi 和bi+1 这三个数字 , 首先bi-1由a-1 . ai组成 bi 由ai和ai+1组成 , bi+1由 ai+1和ai+2组成 , 也就是对于ai-1 ai ai+1 ai+2我们依次考虑删除其中一个后, 看看是否能满足题意, 若不能则输出NO , 若能 ,则判断下一个不符合情况的点
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int N =2e5+9;
#define INF 0x3f3f3f3f
int gcd(int x , int y){
return y ==0?x : gcd(y , x%y);
}
int lcm(int x , int y){
return x*y/gcd(x,y);
}
int n;
void solve(){
cin>>n;
vector<int>a(n+1);
for(int i =1;i<=n;++i)cin>>a[i];
vector<int>b(n+1);
for(int i =1;i<n;++i)b[i] = gcd(a[i] , a[i+1]);
auto check = [&](int p){
auto c = a;
c.erase(c.begin()+1+p);//删除第p个元素
vector<int>d(n+1);
for(int i =1;i<=n-2;++i){
d[i] = gcd(c[i] , c[i+1]);
if(d[i] < d[i-1])return false;
}
return true;
};
for(int i =1;i<n-1;++i){
if(b[i] > b[i+1]){
if(!check(i-1) && !check(i) && !check(i+1) && !check(i+2)){
cout<<"NO"<<endl;
return;
}
}
}
cout<<"YES"<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
int _;cin>>_;
while(_--)solve();
return 0;
}