Codeforces Round #693 (Div. 3) 题解(ABCDE)

A.Cards for Friends

题解:
分开来讨论长和宽就可以,分别对长和宽一直除以二并做一个累乘,得到的结果直接再乘起来就可以
AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<bitset>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define inf -1e12
#define INF 1e12
#define ios std :: ios :: sync_with_stdio(false)
#define PII pair<ll ,ll>

using namespace std;

int main()
{
    ios;
    int t;
    cin >> t;
    while(t--){
        ll w,h,n,ans = 1;
        ll a = 1,b = 1;
        cin >> w >> h >> n;
        while(w % 2 == 0){
            a *= 2;
            w /= 2;
        }
        while(h % 2 == 0){
            b *= 2;
            h /= 2;
        }
//        b = (b == 0 ? 1 : b);
        ans = a * b;
        if(ans >= n) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

B.Fair Division

题解:
先看总数,如果总数是偶数可以分,奇数一定不能分,然后考虑偶数的情况,如果2的个数是奇数个,那么一定有1存在,这个时候可以均分,否则就不能分。
AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<bitset>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define inf -1e12
#define INF 1e12
#define ios std :: ios :: sync_with_stdio(false)
#define PII pair<ll ,ll>

using namespace std;

const int maxn = 1e4 + 10;

int main()
{
   ios;
   int t;
   cin >> t;
   while(t--){
       int n,num_1 = 0,num_2 = 0,sum_1 = 0,sum_2 = 0;
       cin >> n;
       for(int i = 1;i <= n;i++) {
           int x;
           cin >> x;
           if(x == 1) {
               num_1 ++;
               sum_1 ++;
           }
           else {
               num_2 ++;
               sum_2 += 2;
           }
       }
       int sum = sum_1 + sum_2;
       if(sum % 2 == 0) {
           if(num_2 % 2 == 0) cout << "YES" << endl;
           else {
               if(num_1 != 0 && num_1 % 2 == 0) cout << "YES" << endl;
               else cout << "NO" << endl;
           }
       }
       else cout << "NO" << endl;
   }
   return 0;
}

C.Long Jumps

题解:
如果从前往后看的话肯定是超时的。
但是如果我们从后往前看呢?先考虑n然后往后找,那么当我们找到前面的数据的时候,只需要判断 i + a [ i ] i + a[i] i+a[i]是否小于等于n然后把答案记录为 a n s [ i ] = a [ i ] + a [ i + a [ i ] ] ans[i] = a[i] + a[i + a[i]] ans[i]=a[i]+a[i+a[i]]即可,而 a [ i + a [ i ] ] a[i + a[i]] a[i+a[i]]在一开始已经被更新了,所以时间复杂度可以降低到 O ( n ) O(n) O(n)
AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<bitset>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define inf -1e12
#define INF 1e12
#define ios std :: ios :: sync_with_stdio(false)
#define PII pair<ll ,ll>

using namespace std;

const int maxn = 2e5 + 10;

ll a[maxn] = {};

int main()
{
   ios;
   int t;
   cin >> t;
   while(t--){
       int n;
       cin >> n;
       for(int i = 1;i <= n;i++) cin >> a[i];
       for(int i = n;i >= 1;i--){
           if(i + a[i] > n) a[i] = a[i];
           else{
               a[i] = a[i] + a[i + a[i]];
           }
//            cout << "ans = " << a[i] << endl;
       }
       ll maxx = 0;
       for(int i = 1;i <= n;i++) maxx = max(maxx,a[i]);
       cout << maxx << endl;
   }
   return 0;
}

D.Even-Odd Game

题解:
小博弈游戏~我的最爱
其实对于两个人最好的选择就是,如果我当前可以选择的数据比你可选择的小,我就拿走你的,因为只有这样我才有赢得概率,同样如果我的数据比你大我肯定要抢自己的数据,因为对面也会这样子恶心你…
AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<bitset>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define inf -1e12
#define INF 1e12
#define ios std :: ios :: sync_with_stdio(false)
#define PII pair<ll ,ll>

using namespace std;

const int maxn = 2e5 + 10;

ll odd[maxn],even[maxn];

void init()
{
   memset(odd,0,sizeof(odd));
   memset(even,0,sizeof(even));
}

bool cmd(ll a,ll b)
{
   return a > b;
}

int main()
{
   ios;
   int t;
   cin >> t;
   while(t--){
       init();
       int n,cnt_o = 0,cnt_e = 0;
       ll ans_A = 0,ans_B = 0;
       cin >> n;
       for(int i = 1;i <= n;i++) {
           int x;
           cin >> x;
           if(x % 2 == 0) even[++cnt_e] = x;
           else odd[++cnt_o] = x;
       }
       sort(even + 1,even + 1 + n,cmd);
       sort(odd + 1,odd + 1 + n,cmd);
       int p1 = 1,p2 = 1,cnt = 0;
       while(p1 <= cnt_o || p2 <= cnt_e){
           if(cnt % 2 == 0){ // Alice
               if(odd[p1] <= even[p2]){
                   ans_A += even[p2];
                   p2 ++;
               }
               else p1 ++;
               cnt ++;
           }
           else { //Bob
               if(odd[p1] <= even[p2]) p2++;
               else{
                   ans_B += odd[p1];
                   p1 ++;
               }
               cnt ++;
           }
       }
       if(ans_A > ans_B) cout << "Alice" << endl;
       else if(ans_A < ans_B) cout << "Bob" << endl;
       else cout << "Tie" << endl;
   }
   return 0;
}

E. Correct Placement

题解:
这个题目其实是降低难度了,因为他没有让我们排整个队列,而是只要我们找出满足条件的一种情况。
既然h,w的大小关系不确定,那就统一让大的是h,小的是w,这样比较起来更方便而且不会影响结果(题目中描述很清楚了 )。然后我们按照h给序列排序,我们对于当前的序列中的一个人i,排在他后面的人肯定不满足,那就只能去前面判断w,这里贪心一下,我们只用前面w最小的那个人作为答案,记得更新,注意一下h相同的元素是不能更新w的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<bitset>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define inf -1e12
#define INF 1e12
#define ios std :: ios :: sync_with_stdio(false)
#define PII pair<ll ,ll>

using namespace std;

const int maxn = 2e5 + 19;

int ans[maxn] = {};

struct Edge
{
   int id;
   ll w,h;
}a[maxn];

bool cmd(Edge a,Edge b)
{
   if(a.h != b.h) return a.h < b.h;
   else return a.w < b.w;
}

int main()
{
   ios;
   int t;
   cin >> t;
   while(t--){
       int n;
       cin >> n;
       for(int i = 1;i <= n;i++){
           cin >> a[i].h >> a[i].w;
           if(a[i].h < a[i].w) swap(a[i].h,a[i].w);
           a[i].id = i;
       }
       sort(a + 1,a + 1 + n,cmd);
       int p = 1;
       ll minw = INF,minid = 0;
       for(int i = 1;i <= n;i++){
           if(i != 1 && a[i].h != a[i - 1].h){
               while(p < i){
                   if(minw > a[p].w) {
                       minw = a[p].w;
                       minid = a[p].id;
                   }
                   p++;
               }
           }
           if(minw >= a[i].w) ans[a[i].id] = -1;
           else ans[a[i].id] = minid;
       }
       for(int i = 1;i < n;i++) cout << ans[i] << ' ';
       cout << ans[n] << endl;
   }
   return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CUCKyrie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值