iwtgm-17

发布时间 2023-11-07 23:13:31作者: WW爆米花

题目链接

I.

先算出一共有多少天,方便起见,算出考试总天数和发现总天数,两者相减即为差多少天
一周固定三天训练,用同样的方式计算出各有多少天训练,再相减即为答案
要注意的是,算当前周时,训练日期<本周星期的才算已经训练的天数

void solve()
{
    int x0,x1,x2;cin>>x0>>x1>>x2;
    int a0,a1,b0,b1;cin>>a0>>a1>>b0>>b1;
    int pre_total=(a0-1)*7+a1;
    int pos_total=(b0-1)*7+b1;
    int pre_train=(a0-1)*3;
    if(x0<a1)pre_train++;
    if(x1<a1)pre_train++;
    if(x2<a1)pre_train++;
    int pos_train=(b0-1)*3;
    if(x0<b1)pos_train++;
    if(x1<b1)pos_train++;
    if(x2<b1)pos_train++;
    int ans=(pos_total-pre_total)-(pos_train-pre_train);
    cout<<ans;
}

A.

还是进制转换问题
给定的数进制未知,但进制范围只有16,那么暴力枚举
把三个数当成x进制,然后都转换为10进制数进行计算,满足条件即为答案
从大到小枚举较为方便,不用考虑数大于进制的问题

#define int long long
int to_10(int x,string s){//进制,原数
    int ans=0;
    for(int i=s.size()-1,j=0;i>=0;i--,j++){
        int tmp;
        if(s[i]>='0'&&s[i]<='9')tmp=s[i]-'0';
        else if(s[i]>='A'&&s[i]<='F')tmp=s[i]-'A'+10;
        ans+=pow(x,j)*tmp;
    }
    return ans;
}
void solve()
{
    string a,b,c;cin>>a>>b>>c;
    int aa,bb,cc;
    for(int i=16;i>=0;i--){
        aa= to_10(i,a);
        bb= to_10(i,b);
        cc= to_10(i,c);
        if(aa+bb==cc){
            cout<<i<<endl;return ;
        }
    }
}

E.

要求小M的代码最长运行时间,首先先知道最长运行时间在哪里
把运行时长从长到短排序,并记录这个时长属于那个评测机的第几线程
想让代码在这个线程跑有个数量范围
最少就是直接在这个评测机上,且数量等于线程编号
最多就是其他评测机都排满了在加上这个线程的编号
若代码量在这个范围内则可以用这个时长

int k_total;
#define pii pair<int,int>;
map<int,vector<pair<int,int>>,std::greater<int>>mp;
void solve()
{
    int n;cin>>n;
    for(int i=1,k;i<=n;i++){
        cin>>k;k_total+=k;
        for(int j=1,x;j<=k;j++){
            cin>>x;
            mp[x].push_back({i,j});
        }
    }
    int m;cin>>m;
    int l,r;
    for(auto tmp:mp){
        for(int i=0;i<tmp.second.size();i++){
            l=tmp.second[i].second,r=k_total-tmp.second.size()+tmp.second[i].second;
            if(l<=m&&r>=m){
                cout<<tmp.first;return ;
            }
        }
    }
}

L.

相当于一个集合有很多标签,一个学校只要满足任意一个标签就可以进入这个集合
那么我们把这些标签合并,也就是把它们的父亲节点都设成城市的父亲(因为每个学校只在一个城市)
这样我们相当于让关键字都消失了,只剩城市在进行并查集
最后遍历一遍所有学校,学校有唯一的城市,那么就可以轻松判断出各个学校属于哪个集合,题就做完了

#define int long long
int n,m;
map<string,int>mp;//字符串到编号
int father[1010000];//父亲
pair<string,string>school[10010];//学校信息
map<string,int>key;//是否是关键词
int id;//父亲编号
map<int,vector<int>>bar;//集合
int ans[10100];
int find(int x){
    if(x==father[x])return father[x];
    else return father[x]=find(father[x]);
}
void solve()
{
    cin>>n>>m;
    string name,city,s_key;
    for(int i=1;i<=n;i++){
        cin>>name>>city;
        school[i].second=city;school[i].first=name;
        if(mp[city]==0)mp[city]=++id;
    }
    for(int i=1;i<=m;i++){
        cin>>s_key;
        if(key[s_key]==0)
           key[s_key]=++id;
    }
    for(int i=1;i<=id;i++)father[i]=i;
    for(int i=1;i<=n;i++){
        name=school[i].first;
        int fa_city=find(mp[school[i].second]);
        string tmp="";
        for(int j=0;j<name.size();j++){
            if(name[j]=='_'){
                if(key[tmp]>=1){
                    int fa_key=find(key[tmp]);
                    father[fa_key]=father[fa_city];
                }
                tmp="";
            }
            else{
                if(name[j]>='A'&&name[j]<='Z'){
                    tmp+=(char)(name[j]+32);
                }else tmp+=name[j];
            }
        }
        if(key[tmp]>=1){
            int fa_key=find(key[tmp]);
            father[fa_key]=father[fa_city];
        }
    }
    for(int i=1;i<=n;i++){
        int index=find(mp[school[i].second]);
        bar[index].push_back(i);
    }
    for(auto tmp:bar){
        int size=tmp.second.size();
        for(int i=0;i<tmp.second.size();i++){
            ans[tmp.second[i]]=size-1;
        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<endl;
    }
}