当场没在打,出去玩去了,今天开了场virtual, 随便打了一下
A:Ilya and a Colorful Walk 给定一个数组,求最大的区间:最左边和最右边的数不一样。输出区间长度-1 (随便搞下)
int main() {
ios::sync_with_stdio(false); cin.tie(0);
while(cin >> n){
for(int i = 1;i <= n;i++) cin >> a[i];
int ans = 0;
for(int i = 1;i <= n;i++){
if(a[i] != a[n]){
ans = n - i;
break;
}
}
for(int i = n;i >= 1;i--){
if(a[1] != a[i]){
ans = max(ans,i - 1);
break;
}
}
cout << ans << endl;
}
cerr << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
B:Alyona and a Narrow Fridge
有个冰箱,高为h,宽为2。现在要往冰箱里放n个瓶子(注意:按输入顺序放),第二行给出这些瓶子的高度。
放进冰箱时,可以加隔板,隔板不算高度,宽度为2。
从第一个开始放直到第k+1个放不下为止。求k
很明显可以想到贪心策略,排序后,取两个相邻的,但是要注意奇数的时候,因为存在第一个单独放,或者最后一个单独放,模拟一下即可
int main() {
ios::sync_with_stdio(false); cin.tie(0);
while(cin >> n >> h){
for(int i = 1;i <= n;i++) cin >> a[i];
int ans = 0;
for(int i = 1;i <= n;i++){
v.clear();
for(int j = 1;j <= i;j++){
v.push_back(a[j]);
}
v.push_back(0);
sort(v.begin(),v.end());
ll hh = 0;
if(i & 1){
for(int j = i;j >= 2;j -= 2){
int Max = max(v[j - 1],v[j]);
hh += Max;
}
hh += v[1];
ll h1 = 0;
for(int j = 1;j < i;j += 2){
int Max = max(v[j + 1],v[j]);
h1 += Max;
}
h1 += v[i];
hh = min(hh,h1);
}else{
for(int j = i;j >= 1;j -=2 ){
int Max = max(v[j - 1],v[j]);
hh += Max;
}
}
if(hh <= h) ans = i;
}
cout << ans << endl;
}
cerr << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
C:Ramesses and Corner Inversion
给定一个n*m矩阵,你可以进行任意次操作:选择一个至少为2*2的矩形区域,将四个对角的值取反。
问能不能变成下面的矩阵
很容易可以发现,其实不管怎么转换矩阵,对四角的操作都可以由2 * 2的矩阵得来 ,就是按顺序操作,所以直接按顺序旋转即可
void solve(int x,int y){
for(int i = x;i <= x + 1;i++){
for(int j = y;j <= y + 1;j++)
a[i][j] ^= 1;
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
while(cin >> n >> m){
for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) cin >> a[i][j];
for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) cin >> t[i][j];
for(int i = 1;i < n;i++){
for(int j = 1;j < m;j ++){
if(a[i][j] != t[i][j]){
solve(i,j);
}
}
}
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(a[i][j] != t[i][j]){
return cout << "No" << endl,0;
}
}
}
cout << "Yes" << endl;
}
cerr << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
D:Frets On Fire
有一把琴,有n条弦,每条弦有10^18次方个调,初始音调是S_i。(也就是一开始是S_i,接下来是S_i+1,S_i+2,...,S_i+10^18.
有q个询问,每次询问的是这些弦在第i-j个调里面有多少个音
签到,直接差分一分,然后算一下前缀和 ,对于每次二分右端,并且加上左端前缀和
ll a[maxn],s[maxn],d[maxn];
int main() {
ios::sync_with_stdio(false); cin.tie(0);
while(cin >> n){
for(int i = 1;i <= n;i++ ) cin >> a[i];
a[n + 1] = 2e18;
sort(a + 1,a + 1 + n);
for(int i = 1;i <= n;i++) d[i] = a[i + 1] - a[i];
sort(d + 1,d + 1 + n);
for(int i = 1;i <= n;i++) s[i] = s[i - 1] + d[i];
sort(d + 1,d + 1 + n);
ll q;
cin >> q;
vector<ll>ans;
while(q--){
ll l,r;
cin >> l >> r;
ll len = (r - l + 1);
ll id = lower_bound(d + 1,d + 1 + n,r - l + 1) - (d + 1);
ans.push_back((n - id) * len + s[id]);
}
for(auto d:ans) cout << d << " ";
}
cerr << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
现在有一些长度为2的幂次的棍子,第二行给出各个长度的棍子的个数。现在用这些棍子来组三角形,每个三角形只能用三个棍子且不能折断。问能组成的三角形个数
可以考虑即使两个相同的也可以转变成1的 ,所以对于每个直接 / 2 找寻能组合的最多的三角形,然后没有能组成的就考虑 自己 组成,接着把剩下来的供给下次贡献,要按顺序 , 因为 1 1 2 不能组成 , 而 1 2 2 可以组成
int main() {
ios::sync_with_stdio(false);
while(cin >> n){
ll ans = 0,sum = 0;
for(int i = 1;i <= n;i++ ) cin >> a[i];
ll cnt1 = 0,cnt2 = 0;
ll num = 0;
for(int i = 1;i <= n;i++){
if(a[i] >= 2){
int Min = min(a[i] / 2,cnt1);
cnt1 -= Min,a[i] -= Min * 2,sum += Min;
if(a[i] >= 3) sum += a[i] / 3,a[i] %= 3;
if(a[i]) cnt1 += a[i];
}else cnt1 += a[i];
}
cout << sum << endl;
}
cerr << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}