Codeforces Global Round 2 A B C D E

当场没在打,出去玩去了,今天开了场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;
}

E:Pavel and Triangles  

现在有一些长度为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;
}


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值