天梯赛训练

A

查看代码

void solve() {
    int n,res=0;
    cin>>n;
    int idx=0;
    for(int i=1;;++i){
        for(int j=1;j<=i;++j){
            idx++;
            if(idx>n)break;
            res+=i;
        }
        if(idx>n)break;
    }
    cout<<res;
}

 

B

查看代码
 void solve() {
    string s;
    cin>>s;
    int x=0;
    for(int i=0;i<s.size();++i){
        if(s[i]=='1')x++;
    }
    cout<<x;
}

 

C

查看代码
 void solve() {
    string s;
    getline(cin,s);
    int x=0;
    for(int i=0;i<s.size();++i){
        if(s[i]!=' '&&s[i]!='\n')x++;
    }
    cout<<x;
}

 

D

查看代码
 void solve() {
    int a,b,c;
    cin>>a>>b>>c;
    if(a*a>b*c)cout<<"Alice";
    else cout<<"Bob";
}

 

E

思路:每次排在最先接完的人后面,用优先队列维护

查看代码
 void solve() {
    int n,m;
    cin>>n>>m;
    vector<int>a(n);
    for(auto &v:a)cin>>v;
    if(n<=m){
        int ma=0;
        for(auto v:a)ma=max(ma,v);
        cout<<ma;
    }else{
        priority_queue<int,vector<int>,greater<int>>q;
        for(int i=0;i<m;++i)q.push(a[i]);
        for(int i=m;i<n;++i){
            int t=q.top();
            q.pop();
            q.push(t+a[i]);
        }
        int ma=0;
        while(q.size()){
            auto t=q.top();
            q.pop();
            ma=max(ma,t);
        }
        cout<<ma;
    }
}

 

F

思路:实际上就是将n以二进制形式看,若最后一位为1说明为-1,其他情况都可以由二进制数找到

查看代码
 void solve() {
    int n;
    cin>>n;
    if(n%2)cout<<-1;
    else{

        vector<int>ve;
        while(n){
            if(n%2)ve.push_back(1);
            else ve.push_back(0);
            n/=2;
        }

        for(int i=ve.size()-1;i>0;--i){
            if(ve[i]==1){
                cout<<(int)pow(2,i)<<' ';
            }
        }
    }
}

 

G

思路:遇到炸弹其周围的贡献加一

查看代码
 void solve() {
    int n,m;
    cin>>n>>m;
    vector<string>s(n+1);
    vector ve(n+1,vector<int>(m+1,0));
    for(int i=1;i<=n;++i){
        cin>>s[i];
        s[i]=' '+s[i];
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            if(s[i][j]=='*'){
                for(int k=0;k<8;++k){
                    int x=i+dxx[k],y=j+dyy[k];
                    if(x>=1&&x<=n&&y>=1&&y<=m&&s[x][y]=='?'){
                        ve[x][y]++;
                    }
                }
            }
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            if(s[i][j]=='*')cout<<s[i][j];
            else cout<<ve[i][j];
        }cout<<'\n';
    }
}

 

H

思路:模拟过程

查看代码
 void solve() {
    int p[4];
    for(int i=1;i<=3;++i)cin>>p[i];
    string s;
    cin>>s;
    cout<<s[0];
    for(int i=1;i<s.size()-1;++i){
        if(s[i]=='-'){
            char l=s[i-1],r=s[i+1];
            if((l>='0'&&l<='9'&&r>='0'&&r<='9'&&l<r)||(l>='a'&&l<='z'&&r>='a'&&r<='z'&&l<r)){
//                cout<<l<<' '<<r<<'\n';
                string t;
                for(int j=1;;++j){
                    char c=l+j;
//                    cout<<c<<' ';
                    if(c>=r)break;
                    for(int k=0;k<p[2];++k){
                        if(p[1]==3){
                            t.push_back('*');
                        }else if((c>='0'&&c<='9')||p[1]==1){
                            t.push_back(c);
                        }else{
                            t.push_back(c-32);
                        }
                    }
                }
                if(p[3]==2)std::reverse(t.begin(), t.end());
                cout<<t;
            }else cout<<s[i];
        }else cout<<s[i];
    }
    cout<<s.back();
}

 

I

思路:这里数据很大,同int128存。

由给出的构造方法,可以考虑找到每次第一位前缀。每次构造都是前一半的数前缀加0,后一半的数前缀加1,考虑倒着处理,对于最后一次添加,判断当前数在前一半还是后一半,在前一半前缀加0,在后一半前缀加1。还需要更新当前所在构造情况的位置,若在前一半当前的数不变,若在后一半当前的数需要减去前一半的个数。由于后一半的数是前一半的数的倒叙,还需要将位置倒转。倒着处理直到只剩一位

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=2e5+5;
const int MAXN=1e8+5;
const double eps=1e-12;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
const int dxx[8]={-1,-1,0,1,1,1,0,-1};
const int dyy[8]={0,1,1,1,0,-1,-1,-1};
__int128 read()
{
    __int128 res=0;
    char scan[1005];
    scanf("%s",scan);
    for(int i=0;i<strlen(scan);i++)
        res*=10,res+=scan[i]-'0';
    return res;
}
void print(__int128 num)
{
    if(num>9)
        print(num/10);
    putchar(num%10+'0');
}
void solve() {
    __int128 n=read(),k=read();
    k++;
    for(__int128 i=(__int128)1<<n;i>1;i>>=(__int128)1){
        __int128 m=i>>1;
        if(k>m){
            cout<<1;
            k-=m;
            k=m-k+1;
        }else{
            cout<<0;
        }
    }
}
signed main(){
//    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
//    cin>>t;
//    init();
    while(T--){
        solve();
    }
    return 0;
}

 

J

思路:首先考虑最暴力的做法,每次将所有人按规则排序,按规则比赛然后胜者加分。这种做法实际上会超时,再考虑优化,对于按规则排好序的队员,每一场比赛必会有一胜一败者,将所有胜者和败者分类,所有胜者一定是按规则的排好序的,所有败者同理,这样一来就有了两个有序序列,那就可以进行归并排序啦,这样每次就是On的复杂度

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=2e5+5;
const int MAXN=1e8+5;
const double eps=1e-12;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
const int dxx[8]={-1,-1,0,1,1,1,0,-1};
const int dyy[8]={0,1,1,1,0,-1,-1,-1};
struct E{
    int c,id,v;
};
bool cmp(E a,E b){
    if(a.c!=b.c)return a.c>b.c;
    return a.id<b.id;
}
void solve() {
    int n,r,q;
    cin>>n>>r>>q;
    vector<E>ve(2*n);
    for(int i=0;i<2*n;++i){
        cin>>ve[i].c;
        ve[i].id=i;
    }
    for(int i=0;i<2*n;++i)cin>>ve[i].v;
    sort(ve.begin(),ve.end(),cmp);
    vector<E>a(n),b(n);
    while(r--){
        for(int i=0;i<2*n;i+=2){
            if(ve[i].v>ve[i+1].v){
                ve[i].c++;
                a[i/2]=ve[i];
                b[i/2]=ve[i+1];
            }else{
                ve[i+1].c++;
                a[i/2]=ve[i+1];
                b[i/2]=ve[i];
            }
        }
        merge(a.begin(),a.end(),b.begin(),b.end(),ve.begin(),cmp);
    }
//    sort(ve.begin(),ve.end());
    cout<<ve[q-1].id+1;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
//    cin>>t;
//    init();
    while(T--){
        solve();
    }
    return 0;
}

 

K

思路:模拟过程,维护下可行范围的所有类乘客的人数,以及用set维护有多少种,由人数更新种数即可

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=2e5+5;
const int MAXN=1e8+5;
const double eps=1e-12;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
const int dxx[8]={-1,-1,0,1,1,1,0,-1};
const int dyy[8]={0,1,1,1,0,-1,-1,-1};

void solve() {
    int n,l=0;
    cin>>n;
    set<int>se;
    vector<int>cnt(N);
    vector<vector<int>>ve(n);
    for(int i=0;i<n;++i){
        int x;
        cin>>x;
        ve[i].push_back(x);
        cin>>x;
        for(int j=0;j<x;++j){
            int y;
            cin>>y;
            ve[i].push_back(y);
            se.insert(y);
            cnt[y]++;
        }
        while(ve[l][0]<=ve[i][0]-86400){
            for(int j=1;j<ve[l].size();++j){
                if(--cnt[ve[l][j]]==0){
                    se.erase(ve[l][j]);
                }
            }
            l++;
        }
        cout<<se.size()<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
//    cin>>t;
//    init();
    while(T--){
        solve();
    }
    return 0;
}
posted @ 2024-03-20 23:57  bible_w  阅读(9)  评论(0编辑  收藏  举报