Codeforces Round #814 (Div. 2)

game over!


一、A - Chip Game

  • 题目:
    小b和小t最初都在左下角,每次只能向上或者向右走奇数格单位,问谁最先走到右上角?(小b先走)
    -思路:
    这个就是简单的博弈论,我们发现如果只考虑走右边的话,因为每次走的都是奇数,所以如果m是偶数的话,小b一定赢,如果是奇数的话,小t一定赢,然后考虑上面如果n是偶数的话,那小b就会丧失他的先走权,所以就变成小t先走,然后再考虑只走右边的情况,所以说如果全是奇数和全是偶数 小t win,否则都是小bwin
  • 代码:
#include <bits/stdc++.h>
#define int long long 
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define fi first
#define se second
#define pb push_back
#define PII pair<int,int>
#define endl '\n'
using namespace std;

const int N = 2e5 + 100,M = 2e5 + 100,INF = 0x3f3f3f3f,mod = 1e7 + 7;
int n,q;
int h[N], e[M], w[M], ne[M], idx;
int cnt[N], dist[N];
bool st[N];

void solve()
{
    int n,m; cin >> n >> m; // n行m列 向上或者想右走奇数 b先动
    if(n % 2== 1 && m %2 == 1) cout << "Tonya" << endl;
    else if(n % 2 == 0 && m % 2 == 0) cout << "Tonya" << endl;
    else
    cout << "Burenka" << endl;
}
signed main()
{
  ios;
  int T; cin >> T ;while(T -- ) solve();
  return 0;
}
  • 加粗样式

二、B - Mathematical Circus

  • 题目: 给你一个n,k,n是偶数,你是否能让每两个数字a,b满足(a + k) * b % 4 = 0?
  • 思路:
  • 观察发现如果 k % 4 == 0,一定不可能满足条件, 这一对一定要有1个奇数一个偶数,否者两个都是奇数一定不可能是4的倍数,两个偶数的话,一定最后会剩下两个奇数,也是一定不行的 那对于k % 4 = 1,一定可以,我们可以让 (奇数 + k) * 偶数 = 偶数 * 偶数 一定是4的倍数 ,同理对于 k % 4 == 3,也是一样的,而对于k % 4 == 2.那就是 (偶数+ 偶数) * 奇数 ,两个偶数相加一定是4的倍数,所以反过来就行了
  • 代码:
#include <bits/stdc++.h>
#define int long long 
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define fi first
#define se second
#define pb push_back
#define PII pair<int,int>
#define endl '\n'
using namespace std;

const int N = 2e5 + 100,M = 2e5 + 100,INF = 0x3f3f3f3f,mod = 1e7 + 7;
int n,q;
int h[N], e[M], w[M], ne[M], idx;
int cnt[N], dist[N];
bool st[N];

void solve()
{
    int n,k; cin >> n >> k;
    if(k % 4 == 0) cout << "NO" << endl;
    else
    {
        cout << "YES" << endl;
        for(int i = 1;i <= n - 1;i += 2)
        {
            if((i + k) * (i + 1) % 4 == 0)
            cout << i << ' ' << i + 1 << endl;
            else
            cout << i + 1 << ' ' << i << endl;
        }
    }
}
signed main()
{
  ios;
  int T; cin >> T ;while(T -- ) solve();
  return 0;
}

三、C - Fighting Tournament

  • 题目:
    有n个人参加比赛,号码是1 到 n,每个人都有一个武力值,武力值不会出现相同的,然后按照升序排序开始进行比赛,赢得人继续和下一个匹配,输的人直接去到最后面,给你q个询问,问编号为 id的人,进行了k轮,他赢了几场?
  • 思路:
    我们发现如果 k == id - 1,那就代表id这个选手是第一场比赛,所以说如果 k - id < -1,那就代表还没有轮到他,就是0,我们可以记录一下每个选手在前n - 1轮里面都赢了几场,第n轮往后就一定是武力值最大的人一直在赢,如果这个选手在前n - 1场一场没赢,那他后面不可能赢,然后如果他赢了 w[i]场,如果k无线大那他最多也就是赢w[i]场,我们对于前n - 1场,发现如果问的不是第一个人,那答案就是 k - id + 2,如果是第一个人就是 k - id + 1,特判一下最大的那个人
    -代码:
#include <bits/stdc++.h>
#define int long long 
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define fi first
#define se second
#define pb push_back
#define PII pair<int,int>
#define endl '\n'
using namespace std;

const int N = 2e5 + 100,M = 2e5 + 100,INF = 0x3f3f3f3f,mod = 1e7 + 7;
int w[N],a[N],b[N];

void solve()
{
   int n,q; cin >> n >> q;
   
   int mx = -1;
   for(int i = 1;i <= n;i ++ ) cin >> a[i],b[i] = a[i],mx = max(mx,b[i]),w[i] = 0;
   
   int ix = 1;
   
  for(int i = 1;i <= n - 1;i ++ ) 
  {
      if(a[i] > a[i + 1]) // 第i轮  
      {
          w[ix]++;
          a[i + 1] = a[i];
      }
      else
      {
          w[i + 1]++;
          ix = i + 1;
      }
       
     
  }
  // for(int i = 1;i <= n;i ++ ) cout << w[i] << endl;
   while(q -- )
   {
       
      int id,k; cin >> id >> k;
      
      if(w[id] == 0)
      {
           cout << "0" << endl;
      }
      else if(k - id < -1) cout << "0" << endl;
      else if(b[id] != mx)
      {
          if(id != 1)
          cout << min(k - id + 2,w[id]) << endl;
          else
          cout << min(k - id + 1,w[id]) << endl;
      }
      else
      {
          if(id == 1)
          cout << k - id + 1 << endl;
          else
          cout << k - id + 2 << endl;
      }
   }
}
signed main()
{
  ios;
  int T; cin >> T ;while(T -- ) solve();
  return 0;
}

四、D2 - Burenka and Traditions (hard version)

  • 题目:
    给你一个数组,你可以选择L , R, x, 让[L,R]里面的所有元素都异或x,问你最少几秒可以把数组里面的元素都变成0,每次操作花费时间 (R - L + 1) / 2 上取整
  • 思路:
    如果区间长度是1,花费1,区间长度2,花费1, … 那我们就可以拆了,比如如果选择的区间长度是4,那拆成2 2 花费的时间也是一样的,3 就拆成2 1 ,所以我们选择L,R就是选择长度为1,或者为2的,那我们可以发现只要操作几次以后为0了,那前面的数就都不用要了,所以0就相当于分界线,比如A B C D四个数字的异或是0,那最少就需要的时间是 3 秒,也就是异或为0的数字尽量多,这道题最多n秒,所以遇到一次0就减一
    -代码:
#include <bits/stdc++.h>
#define int long long 
#define ios ios::sync_with_stdio(0),cin.tie(0)
#define fi first
#define se second
#define pb push_back
#define PII pair<int,int>
#define endl '\n'
using namespace std;

const int N = 2e5 + 100,M = 2e5 + 100,INF = 0x3f3f3f3f,mod = 1e7 + 7;
int w[N],a[N],b[N];
int n;
void solve()
{

    cin >> n;
    for(int i = 1 ; i <= n ; i ++ ) cin >> a[i];
    
    int res = n;
    int ans = 0;
    set<int> s;
    s.insert(0); // 0必须存在
    for(int i = 1; i <= n ; i ++ )
    {
        ans ^= a[i];
        if(s.count(ans)) s.clear(), res--;
        s.insert(ans); //如果异或为0的话,也是需要加进去的,否则在下一次判断的时候就判断不了了
    }
    cout << res << endl;

   
}
signed main()
{
  ios;
  int T; cin >> T ;while(T -- ) solve();
  return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值