Codeforces Round #814 (Div. 2)题解

全程面向样例编程

D赛中没出,要是补了或许会来题解这加点

思路全写在注释里了

A. Chip Game

可移动步数为奇数

起点为(1,1)

只能往上或右走

走到无路可走时肯定只能是到了(n,m)点

考虑数值的奇偶性

如果边界坐标为偶数,那一步到位,就能让对方无路可走

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define x first
#define y second
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define rep(a,b,c) for(int a=b;a<c;a++)
#define rep2(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>c;a--)
#define per2(a,b,c) for(int a=b;a>=c;a--)
#define YES {puts("YES");return;}
#define NO {puts("NO");return;}
#define TW {puts("Tonya");return;}
#define BW {puts("Burenka");return;}
int a[101],b[101];
void solve()
{
    int n,m;cin>>n>>m;
    if(n==1&&m==1)TW
    else if(n%2&&m%2==0||n%2==0&&m%2)BW
    else TW
    //一奇一偶Bwin,不然twin
    //因为n或m为偶数的话,通过移动奇数步就达到边界
    //剩下的只有偶数步能走
    //可以走两次
}
signed main(void)
{
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    int t;cin>>t;
    while(t--)solve();
}

B. Mathematical Circus

k要是奇数

前者放奇数

偶数×偶数

都有因子2,乘起来有因子4

k为偶数

讨论k是否为4的倍数

k为4的倍数

奇数没人带,偶数中不是4的倍数的,还要被4的倍数带,因为它加了k后不能自成一家

所以这种情况下NO

k不是4的倍数

那好办

偶数都可以自成一家了

n为偶数

说明奇数偶数数量相等

给每个奇数分配一个偶数,game over

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define x first
#define y second
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define rep(a,b,c) for(int a=b;a<c;a++)
#define rep2(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>c;a--)
#define per2(a,b,c) for(int a=b;a>=c;a--)
#define YES {cout<<"YES"<<endl;}
#define NO {cout<<"NO"<<endl;return;}

int a[100010];
void solve()
{
    int n,k;cin>>n>>k;
    if(n==2&&k==0)NO
    if(k%4==0)NO
    //需要k无法整除4且k为偶数
    //如果k不能被4整除,但能被2整除
    //它和不能被4整除的偶数加起来为4的倍数
    //那么就用非4的倍数但是是偶数的数去带奇数
    //剩下的能被4整除的偶数,继续带奇数
    //因为n为偶数,所以所有偶数都带一个相邻的奇数,刚好分配光
    //如果k能被4整除,那和不能被4整除的偶数加起来仍然不能被4整除
    //而这里的奇数还没人带
    //所以k要是4的倍数,就NO
    if(k%2)
    {
        YES
        for(int i=1;i<=n;i+=2)
        {
            cout<<i<<" "<<i+1<<endl;
        }
    }
    else
    {
        YES
        for(int i=2;i<=n;i+=4)
        {
            cout<<i<<" "<<i-1<<endl;
        }
        for(int i=3;i<=n;i+=4)
        {
            cout<<i<<" "<<i+1<<endl;
        }
    }
}
signed main(void)
{
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    int t;cin>>t;
    while(t--)solve();
}

C. Fighting Tournament

大模拟

谁赢就把话语权分给它

中间拥有过话语权但最后失去的,有点惨

所以单独开了一个一维数组mxcnt来维护它职业生涯中的比赛到最后一场时,总共赢的场数

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define x first
#define y second
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define rep(a,b,c) for(int a=b;a<c;a++)
#define rep2(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>c;a--)
#define per2(a,b,c) for(int a=b;a>=c;a--)
#define YES {puts("YES");return;}
#define NO {puts("NO");return;}
int a[200010];
map<PII,int> cnt;
int mxcnt[200010];
int win[200010];
void solve()
{
    int n,q;cin>>n>>q;
    cin>>a[1];
    cnt.clear();
    int mx=a[1],pos=1;
    for(int i=0;i<=n;i++)mxcnt[i]=0;
    for(int i=2;i<=n;i++)
    {
        cin>>a[i];

        if(a[i]>mx)mx=a[i],pos=i;
        mxcnt[pos]=cnt[{pos,i-1}]=cnt[{pos,i-2}]+1;
        //mxcnt是为了记录不是最终mx值的数,最终赢的场数
        //因为这里如果用map来叠加的话,要给后边所有的cnt[{pos,r}]
        //(这里r指从a[pos]输之后到第n-1场)都给更新迭代了
        //所以另外开了一个mxcnt一维数组
        win[pos]=i-1;

    }


    while(q--)
    {
        int i,k;cin>>i>>k;
        if(k<n-1)
        {
            if(k<win[i])cout<<cnt[{i,k}]<<endl;
            //第k场如果在第i个数出场前
            //因为每次map都清空过,所以为初值0
            else cout<<mxcnt[i]<<endl;
            //如果在第k场后
            //那么已经定了乾坤,不会再变,就是mxcnt[i]
        }
        else if(i!=pos) cout<<mxcnt[i]<<endl;
        else cout<<k-(n-1)+cnt[{i,n-1}]<<endl;
    }
}
signed main(void)
{
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    int t;cin>>t;
    while(t--)solve();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值