Codeforces Round 908 (Div. 2) (思维 + 鸽巢原理+枚举)

A:赢得那个人肯定是最后一个人才结束

所以直接输出最后一个

#include
using namespace std;
const int N = 1e6+10,mod= 998244353;
#define int long long
typedef long long LL;
typedef pair PII;

int n,m,k;
int a[N],s[N];
void solve()
{
    
    cin>>n;
    string s;
    cin>>s;
    cout<>t;
    while(t--) solve();
}

B:

只要满足两个条件,所以只要有两对相同数字的就行

#include
using namespace std;
const int N = 1e6+10,mod= 998244353;
#define int long long
typedef long long LL;
typedef pair PII;

int n,m,k;
vector g[N];
int a[N];
int res[N];
void solve()
{
    for(int i=0;i<=100;i++)
    {
        g[i].clear();
    }
    cin>>n;
    int cnt=0;
    map mp;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        mp[x]++;
        if(mp[x]==2) cnt++;
        g[x].push_back(i);
    }
    if(cnt<2){
        cout<<"-1\n";
        return ;
    }
    int now=0;
    
    for(int i=1;i<=100;i++)
    {
        if(g[i].empty()) continue;
        res[g[i][0]]=1;
        if(g[i].size()==1) continue;
        int tar=3;
        
        if(now==0) tar=2;
        now^=1;
        for(int j=1;j>t;
    while(t--) solve();
}

C:

观察最后一个数,每次都是由最后一个数操作才得到当前序列的

所以直接从最后一个数开始枚举上去即可,如果出现环或者操作次数大于n就满足

举例子吧

比如 7 2 1 是由最后一个数1操作来的,所以上一个序列是

1 7 2

然后还是由最后一个数2操作来的,所以上一个序列是

7 2 1

然后继续由最后一个属1操作来的,所以上一个序列是

1 7 2

然后就循环了一直,因为它可以让a数组任意,所以只要次数或者有个环就能满足

每次数变成当前最后一个数即可

#include
using namespace std;
const int N = 1e6+10,mod= 998244353;
#define int long long
typedef long long LL;
typedef pair PII;

int n,m,k;
vector g[N];
int a[N];
int b[N];
void solve()
{
    cin>>n>>k;
    for(int i=0;i>a[i];
    }
    int idx=n-1;
    map mp;
    for(int i=1;i<=min(n,k);i++){
        if(a[idx]>n){
            cout<<"No\n";return ;
        }
        idx=(idx-a[idx]);
        idx=(idx+n)%n;
        if(mp[idx]>0){
            cout<<"Yes\n";
            return ;
        }
        mp[idx]++;
    }
    cout<<"Yes"<<"\n";
}

signed main()
{
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    int t=1;
    cin>>t;
    while(t--) solve();
}

D:

我是这样想的,让b数组随便插入而且还要非单调递增

所以肯定让b数组从大到小插入嘛

然后插入到a哪里呢,

肯定从a数组后面第一个出现的数a[i]插入比如a[i]小于等于的b[i]

比如

现在要插入6 

数组有

7  x x  7  x  x 7

你肯定直接插入到最后一个7后面嘛,毕竟越后面插入,中间用得到6的数更少

#include
using namespace std;
const int N = 1e6+10,mod= 998244353;
#define int long long
typedef long long LL;
typedef pair PII;

int n,m,k;
vector g[N];
int a[N];
int b[N];
void solve()
{
    cin>>n>>m;
    map mp;
    for(int i=1;i<=n;i++){
        g[i].clear();
        cin>>a[i];
    }
    for(int i=1;i<=m;i++) cin>>b[i];
    sort(b+1,b+1+m);
    int idx=1;
   
    for(int i=n;i>=1;i--)
    {
        while(idx<=m&&a[i]>=b[idx])
        {
            g[i].push_back(b[idx]);
            idx++;
        }    
    }
     for(int i=m;i>=idx;i--) cout<());
        for(auto x:g[i]) cout<>t;
    while(t--) solve();
}

E:

这个题是个套路题,我见过好多次了...

直接枚举L 到 R的总和就行

因为n=10w,由于鸽巢原理,就是L到R总和很大,由于n的不同数有10w个

我10w个数枚举完后,当前数肯定没有的,然后个数取当前数就行了,答案肯定是0

否则,直接枚举数取当前值就行

然后就直接枚举就行

#include
using namespace std;
const int N = 1e6+10,mod= 998244353;
#define int long long
typedef long long ll;
typedef pair pii;
const long long inf=1e17;
int n,m,k;
vector g[N];
void solve()
{
    int m;cin>>m;
    
    //一维数字的值,二维{在哪出现,出现次数}
    map>mp;
    vector>e(m);
    int mnL=0,mxR=0;
    for(int i=0;i>n>>l>>r;
        mnL+=l,mxR+=r;
        vectora(n),c(n);
        for(int j=0;j>a[j];
        for(int j=0;j>c[j];
        for(int j=0;jinf||!mp.count((ll)i)){
            ok=0;
            break;
        }
    }
 
    if(!ok){
        cout<<0<<'\n';
        return;
    }
 
    ll ans=inf;
    for(ll i=mnL;i<=mxR;i++){
        ll res=0;
        //假设都选r个数字
        ll s=mxR;
        for(auto &[id,cnt]:mp[i]){
            auto &[n,l,r,sum]=e[id];
            //还原成不选的状态
            s-=r;
            //最少选==i的数字的数量
            ll t=0;
            if(sum-cnt>t;
    while(t--) solve();
}

你可能感兴趣的:(算法,codeforce)