学习笔记16:abc337

克里斯蒂娜   !   !   !

Toyota Programming Contest 2024#1(AtCoder Beginner Contest 337) - AtCoder

B

题目说明了只有 ABC三种字符,那么只要判断下当前字符是否比前一个小即可

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>

using namespace std;
typedef long long LL;
#define int long long
typedef pair<int,int> PII;
const int N=1000010;
int a[N],b[N];
int n,m;
void solve(){
    string x;
    cin>>x;

    for(int i=1;i<x.size();i++){
        if(x[i]<x[i-1]){
            cout<<"No"<<endl;
            return;
        }
    }
    cout<<"Yes"<<endl;

}
signed main(){
    
    int t=1;
    //cin>>t;
    while(t--){
        solve();
    }
}
        

C

模拟一下即可

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>

using namespace std;
typedef long long LL;
#define int long long
typedef pair<int,int> PII;
const int N=1000010;
int a[N],ans[N];
int n,m;

struct edge
{
    int x,id;
}b[N];
void solve(){
    int n;
    cin>>n;
    int root;
    std::vector<int> v(n+1);
    for (int i = 1; i <=n; ++i)
    {
        cin>>a[i];
        if(a[i]==-1)root=i;
        else v[a[i]]=i;
    }
    ans[root]=1;
    queue<int>q;
    q.push(root);
    while(q.size()){
        int t=q.front();
        q.pop();
        if(!t) break;
        ans[v[t]]=ans[t]+1;
        q.push(v[t]);
    }
    for(int i=1;i<=n;i++){
        // cout<<ans[i]<<" ";
        b[i].x=ans[i];
        b[i].id=i;
    }
    sort(b+1,b+1+n,[&](edge xx,edge yy){
        return xx.x<yy.x;
    }); 
    for (int i = 1; i <=n; ++i)
    {
        cout<<b[i].id<<" ";
    }
}
signed main(){
    
    int t=1;
    //cin>>t;
    while(t--){
        solve();
    }
}
        

D

横竖模拟一下,遇到'x'需要清空

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>

using namespace std;
typedef long long LL;
#define int long long
typedef pair<int,int> PII;
const int N=1000010;
int a[N],ans[N];
int n,m;

string str[N];
void solve(){
    int n,m,k;
    cin>>n>>m>>k;
    for( int i = 0 ; i < n ; i ++ ){
        cin >> str[i] ;
    }
    int ans1=1e18,ans2=1e18;
    if(n>=k){
        for(int i=0;i<m;i++){
            queue<char>q;
            int sum1=0,sum2=0;
            for(int j=0;j<n;j++){
                if(str[j][i]=='x'){
                    sum1=0;sum2=0;
                    while(q.size())q.pop();
                }else{
                    if(str[j][i]=='.')sum1++;
                    else sum2++;
                    q.push(str[j][i]);
                    if(q.size()>k){
                        int t=q.front();
                        q.pop();
                        if(t=='.')sum1--;
                        else sum2--;
                    }
                    if(q.size()==k){
                        ans1=min(ans1,sum1);
                    }
                }

            }
        }
    }
    if(m>=k){
        
        
        for(int i=0;i<n;i++){
            queue<char>q;
            int sum1=0,sum2=0;
            for(int j=0;j<m;j++){
                if(str[i][j]=='x'){
                    sum1=0;sum2=0;
                    while(q.size())q.pop();
                }else{
                    if(str[i][j]=='.')sum1++;
                    else sum2++;
                    q.push(str[i][j]);
                    if(q.size()>k){
                        int t=q.front();
                        if(t=='.')sum1--;
                        else sum2--;
                        q.pop();
                    }
                    if(q.size()==k){
                       // cout<<j<<endl;
                        ans2=min(ans2,sum1);
                    }
                }

            }
        }
    }
    //cout<<ans1<<" "<<ans2<<endl;
    int ans=min(ans1,ans2);
    if(ans==1e18) cout<<-1<<endl;
    else cout<<ans<<endl;
}
signed main(){
    
    int t=1;
    //cin>>t;
    while(t--){
        solve();
    }
}
        

E

经典的老鼠喝毒药问题

用二进制模拟解决

每一个朋友当成一个数位

之后输入的字符串组成一个二进制数,把它转化成十进制即是答案

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>

using namespace std;
typedef long long LL;
#define int long long
typedef pair<int,int> PII;
const int N=1000010;
int a[N],ans[N];
int n,m;
vector<int>v[N];
string str[N];
void solve(){
    int n,m,k;
    cin>>n;
    string x;
    if(n==1){
        cout<<1<<endl;
        cout<<1<<" "<<1<<endl;
        cin>>x;
        cout<<1<<endl;
        return;
    }

    int now=1;
    int res=0;
    while(now<n){
        now<<=1;
        res++;
    }
    cout<<res<<endl;
    for(int i=1;i<=n;i++){
        for(int j=res-1;j>=0;j--){
            if(i>>j&1) v[j+1].push_back(i);
        }
    }
    for(int i=res;i>=1;i--){
        cout<<v[i].size()<<" ";
        for(auto c:v[i]) cout<<c<<" ";
        cout<<endl;
    }
    
    cin>>x;

    int ans=0;
    for(int i=0;i<x.size();i++){
        if(x[i]=='1')ans+=(1<<(x.size()-1-i));
    }
    if(ans)cout<<ans<<endl;
    else cout<<(1<<res)<<endl;
}
signed main(){
    
    int t=1;
    while(t--){
        solve();
    }
}
        

F

感觉这个题的数据很弱啊,之前一次提交把a[r] 误写成a[i]只错了一个数据

分析:手动模拟一下这个过程,我们会发现操作的过程可以用双指针模拟

这个有一个细节,如果一个数超过k个,并且还有空的盒子,那么它后续的数可以放进这个空的盒子里(当然也不能超过k个)

放入和拿出的时候都需要维护

在维护的时候可以用数学的小技巧

(num-1)/k+1

当前该数字应该在第几个同样装了该数字的盒子里

比如k=3

盒子1已经装了3个1,这是又来一个1那就是(4-1)/3+1=2,在第二个盒子里

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<map>

using namespace std;
typedef long long LL;
#define int long long
typedef pair<int,int> PII;
const int N=1000010;
int n,m,k;
int a[N];
void solve(){
    cin>>n>>m>>k;
    int r=1;
    vector<int>sum(N);
    int cnt=0;
    deque<int>q;
    map<int,int>mp;
    int ans=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i+n]=a[i];
        mp[a[i]]++;
       // mp[a[i]]=min(k,mp[a[i]]);
    }
    for(int i=1;i<=n;i++){
        if(q.size()){
            int t=q.front();
            
            if(sum[t]-1==0){
               cnt--; 
               ans-=min(mp[t],k);
            }else if((sum[t]-1)/k+1!=(sum[t]-2)/k+1){
                cnt--;
                ans+=k*((sum[t]-2)/k+1);
                ans-=min(mp[t],k*((sum[t]-1)/k+1));
            }
            sum[t]--;
            q.pop_front();
        }
        while(cnt<m && r<=i+n-1){
            q.push_back(a[r]);
            if(!sum[a[r]]){
                cnt++;
                ans+=min(mp[a[r]],k);
            }else if(sum[a[r]]/k+1!=(sum[a[r]]-1)/k+1){
                cnt++;
                ans-=k*((sum[a[r]]-1)/k+1);
                ans+=min(mp[a[r]],k*(sum[a[r]]/k+1));
            }
            sum[a[r]]++;
            r++;
        }
        cout<<ans<<endl;
    }
}
signed main(){
    
    int t=1;
    //cin>>t;
    while(t--){
        solve();
    }
}
        

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值