Educational Codeforces Round 38 (Rated for Div. 2)

A.
签到模拟题

#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
bool isvowel(char c)
{
    return c=='a'||c=='e'||c=='i'||c=='o'||c=='u'||c=='y';
}
int main()
{
    int n,i,j;string str;
    cin>>n>>str;
    i=1;
    while(i<str.size()){
        if(isvowel(str[i])&&isvowel(str[i-1]))
            str.erase(i,1);
        else i++;
    }
    cout<<str<<endl;

    return 0;
}

B.
根据那些奖项离谁更近判断由谁去拿即可,其实考虑到数据范围暴力扫一波似乎也爆不了,不过这里写了一发二分。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int n,i,j,pos,num[100005];
    cin>>n;
    for(i=1;i<=n;i++)scanf("%d",&num[i]);
    pos=upper_bound(num+1,num+1+n,5e5)-num;
    if(pos>n)
        cout<<num[n]-1<<endl;
    else if(pos<=1)
        cout<<1e6-num[1]<<endl;
    else{
        cout<<max((int)1e6-num[pos],num[pos-1]-1)<<endl;
    }

    return 0;
}

C.
这里写图片描述

如果是求解这个问题的话,答案就是n^2-(n/k)向下取整 原因可以看原题解。
那么现在的话我们只要枚举每个n看看有没有符合要求的k满足x即可。

#include<cstdio>
#include<iostream>
#include<cmath>
int t,x,a,b,f,i;
int main() {
    for (scanf("%d", &t); t--;) {
        scanf("%d", &x);f = 0;
        for (i = 0; i < 39999; i++)//枚举n
            if ((a = i * i - x) > 0)
                if ((b = sqrt(a)) * b == a)//如果这是个整数
                    if (i / b > i / (b + 1)) {//?
                        printf("%d %d\n", i, i / b);
                        f = 1;break;
                    }
        if (!f) puts("-1");
    }

    return 0;
}

D.
很有意思的一道题,事实上,这题里面的路径什么的跟普通的最短路径没有什么不同,但是他要求的是每个点到其他点的最短路径加上该点票价的最小值。但是,显然每个点跑一遍最短路是不现实的。然而题目刚好有个神奇的地方,即,因为我们是要求每个点出发的花费最小值,因此我们可以把每个点的票价当做这个点的初始距离,然后加进dijkstra的堆,这样,每次都会找出当前最近的点,也就意味着这个点的方案达到了最优。看起来,这题用SPFA似乎没法做?也算是非常有意思了。

#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int n,m;ll a[N];
ll  dis[N];
struct edge{
    int to;ll cost;
};
vector<edge>G[N];
typedef pair<ll,int>P;
bool used[N];
int main()
{
    int i,j,k;
    cin>>n>>m;
    memset(dis,0x3f,sizeof(dis));
    for(i=1;i<=m;i++){
        int a,b;ll c;
        scanf("%d%d%lld",&a,&b,&c);c*=2;
        G[a].push_back(edge{b,c});
        G[b].push_back(edge{a,c});
    }
    priority_queue<P,vector<P>,greater<P> >que;
    for(i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        que.push(P(a[i],i));
    }
    while(!que.empty()){
        P p=que.top();que.pop();
        if(used[p.second])continue;
        used[p.second]=true;dis[p.second]=p.first;
        for(auto a:G[p.second]){
            if(dis[a.to]>dis[p.second]+a.cost){
                dis[a.to]=dis[p.second]+a.cost;
                que.push(P(dis[a.to],a.to));
            }
        }
    }
    for(i=1;i<=n;i++)
        cout<<dis[i]<<' ';
    cout<<endl;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值