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 + 1int 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+mcout<<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;
}