upc2021秋组队训练赛第一场 ICPC North Central NA Contest 2020

牛客链接

D: Substring Characters

对于一个字符串 s s s,求所有不同的最短连续子串的数量,要求不能是 s s s本身并且子串的不同字符的数量与 s s s的不同字符的数量相同。
题意比较绕,最短的含义指的是删除某个子串 t t t的前缀或后缀后,就无法保证不同字符的数量与 s s s相同了。比如 10411 10411 10411,可以删除后缀 11 11 11,变成 104 104 104
双指针,队友写的

#include <bits/stdc++.h>
using namespace std;
char str[300];
map<char, bool>mp;
map<char, int>mpp;
map<string, bool> mppp;
void solve()
{
    mp.clear();
    mpp.clear();
    mppp.clear();
 
    int len = strlen(str);
    int sum = 0;
    for(int i = 0; i < len; i++)
    {
        if(mp[str[i]] == 0) sum++;
        mp[str[i]] = 1;
    }
 
    int l = 0, r = 0, ans = 0, tmp = 0;
    for(int i = 0; i < len; i++)
    {
        while(r < len)
        {
            if(mpp[str[r]] == 0) tmp++;
            mpp[str[r]]++;
            r++;
            if(tmp == sum)
            {
                while(tmp == sum)
                {
                    if(mpp[str[i]] == 1) tmp--;
                    mpp[str[i]]--;
                    i++;
                }
                i--;
 
                string s = "";
                for(int j = i; j < r; j++)
                {
                    s += str[j];
                }
                if(i == 0 && r == len)
                {
                    puts("0");
                    return ;
                }
                else if(mppp[s] == 0)
                {
                    mppp[s] = 1;
                    ans++;
                }
                if(r == len)
                {
                    cout << ans << endl;
                    return ;
                }
                break;
            }
        }
        if(r == len)
        {
            cout << ans << endl;
            return ;
        }
    }
 
}
 
int main()
{
    while(~scanf("%s", str))
    {
        solve();
    }
    return 0;
}

E: Curve Speed

在这里插入图片描述
给出 r , s r,s r,s,求 v v v

int main() {
    double a,res;
    while(cin>>a>>res){
        double ans=sqrt(a*(res+0.16)/0.067);
        printf("%.d\n",(int)(ans+0.5));
    }   
    return 0;
}

F: Agamemnon’s Odyssey

给定一棵 N 个点的带边权树,可以任选一点作为起点,每条边最多经过 k 次,但只有在首次经过时才会贡献大小等于边权的价值,求价值和最大的一条路径。

k = = 1 k==1 k==1时,答案是树的直径;
k > 1 k>1 k>1时,答案是所有边权之和

const int maxn=2e5+100;
 
ll n,k,ans;
vector<PLL>g[maxn];
 
ll dfs(int u,int fa){
    ll dist=0ll,d1=0ll,d2=0ll;
    for(auto t:g[u]){
        int j=t.first,w=t.second;
        if(j==fa) continue;
        ll d=dfs(j,u)+w;
        dist=max(dist,d);
        if(d>=d1) d2=d1,d1=d;
        else if(d>d2) d2=d;
    }
    ans=max(ans,d1+d2);
    return dist;
}
 
int main() {
    n=read,k=read;
    rep(i,1,n-1){
        int u=read,v=read,w=read;
        if(k>1) ans+=w;
        else g[u].push_back({v,w}),g[v].push_back({u,w});
    }
    if(k==1) dfs(1,-1);
    printf("%lld\n",ans);
     
     
    return 0;
}

H: Digital Speedometer

模拟

int main() {
    double tf,tr;
    cin>>tf>>tr;
    double s;
    double las=100000000;
    while(cin>>s){
        double t=floor(s);
        if(s==0) las=0;
        else if(s>0&&s<1) las=1;
        else if(s>=t&&s<t+tf) las=floor(s);
        else if(s>t+tr&&s<t+1) las=ceil(s);
        else if(s>=t+tf&&s<=t+tr){
            if(s<las) las=ceil(s);
            else las=floor(s);
        }
        printf("%.0f\n",las);
    }
     
     
     
     
    return 0;
}

K: ICPC Record Matching

模拟。

const int maxn=2e5+100;
 
string cul(string s){
    string res="";
    for(int i=0;s[i];i++){
        if(s[i]>='A'&&s[i]<='Z'){
            int t=s[i]-'A';
            res+=(t+'a');   
        }
        else res+=s[i];
    }
    return res;
}
 
struct node{
    string first,last,email;
};
 
bool cmp(node a,node b){
    return cul(a.email)<cul(b.email);
}
 
vector<node>g[2];
set<PSS>s_name[2];
set<string>s_email[2];
vector<node>ans[2];
 
 
 
int main() {
    string str;
    while(getline(cin,str)){
        if(str.size()==0) break;
        //cout<<str<<endl;
        stringstream ss;
        ss<<str;
        string a,b,c;
        ss>>a>>b>>c;
        g[0].push_back({a,b,c});
        s_name[0].insert({cul(a),cul(b)});
        s_email[0].insert(cul(c));
    }
    //puts("*****");
    while(getline(cin,str)){
        //cout<<str<<endl;
        stringstream ss;
        ss<<str;
        string a,b,c;
        ss>>a>>b>>c;
        g[1].push_back({a,b,c});
        s_name[1].insert({cul(a),cul(b)});
        s_email[1].insert(cul(c));
    }
    bool flag=1;
    for(int k=0;k<2;k++){
        for(auto t:g[k]){
            string a=cul(t.first),b=cul(t.last),c=cul(t.email);
            PSS ab={a,b};
            int ant=1-k;
            if(!s_name[ant].count(ab)&&!s_email[ant].count(c)){
                ans[k].push_back(t);
                flag=0;
            }
        }
    }
    if(flag) puts("No mismatches.");
    else{
        for(int k=0;k<2;k++){
            sort(ans[k].begin(),ans[k].end(),cmp);
            for(auto t:ans[k]){
                if(k==0) cout<<"I ";
                else cout<<"O ";
                cout<<t.email<<" "<<t.last<<" "<<t.first<<"\n";
            }
        }
    }
     
     
     
     
     
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆沙睡不醒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值