Educational Codeforces Round 47

B. Minimum Ternary String 

题意:给了只含0,1,2的字符串,相邻的0和1、1和2可以交换,0和2不能交换,求可以交换成的字典序最小的字符串。

分析:贪心,小的放到大的数前面,0不能放到2前面,以第一个2为基准,它后面的1都放在它前面,它前面的0最前面,前面的1和后面的1是在一起的

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
char s[maxn];
int main()
{
    scanf("%s",s);
    int len = strlen(s);
    int pos = -1;
    for(int i = 0; i < len; i++)
    {
        if(s[i] == '2')
        {
            pos = i;
            break;
        }
    }
    if(pos == -1)
    {
        for(int i = 0; i < len; i++)
        {
            if(s[i] == '0')
                printf("0");
        }
        for(int i = 0; i < len; i++)
        {
            if(s[i] == '1')
                printf("1");
        }
        printf("\n");
    }
    else
    {
        for(int i = 0; i < pos; i++)
        {
            if(s[i] == '0')
                printf("0");
        }
        for(int i = 0; i < len; i++)
        {
            if(s[i] == '1')
                printf("1");
        }
        for(int i = pos; i < len; i++)
        {
            if(s[i] == '0')
                printf("0");
            else if(s[i] == '2')
                printf("2");
        }
        printf("\n");
    }

    return 0;
}

C. Annoying Present

题意:有n个数,m组系数对,每组系数对包括x和d,其中d需要乘以一个距离和,这个距离和等于 ∑|i - j| (1 =< j <= n,i为选定的坐标),求(d1* |i - j| + d2 * |i - j| + ... dm * |i - j|)/n + x1 + x2+ ... +xm的最大值

分析:根据所给的di的正负选取不同的|i - j|,正数选择的肯定是最大的,负数选择的肯定是最小的,最大的选的基准点i就是最边上,最小的选择基准点i在中间

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
char s[maxn];
int main()
{
    int n,m;
    cin>>n>>m;
    int x = n / 2 + 1;
    ll d1 = 0,d2 = 0;
    for(int i = 1; i <= n; i++)
        d1 += abs(x - i);
    for(int i = 1; i <= n; i++)
        d2 += abs(n - i);
    ll sum = 0,ans = 0;
    for(int i = 1; i <= m; i++)
    {
        int a,b;
        cin>>a>>b;
        sum += a;
        if(b >= 0)
        {
            ans += (d2 * b);
        }
        else
        {
            ans += (d1 * b);
        }
    }
    double res = 1.0 * sum + ans * 1.0 / n;
    printf("%.7f\n",res);
    return 0;
}

D. Relatively Prime Graph

题意:给了n和m,代表有n个顶点和m条边,求能否构建出一个联通图,使得这个图的相邻的顶点互素

分析:因为n和m的范围都是1e5,利用n直接暴力肯定超时,连通图(简单图)边数最多为n * (n - 1) / 2,所以m为1e5时一定不需要1e5个顶点,通过打表发现只需要不超过1000个顶点就够了,n的上限是1000,直接暴力

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
ll a[maxn];
vector<pair<int,int> >edge;
void dabiao()
{
    int n = 1;
    ll sum = 0;
    while(n * (n - 1) / 2 - sum  <= 1e5)
    {
        for(int i = 2; i <= n; i++)
            a[i] = n / i;
        sum = 0;
        for(int i = 1; i <= n; i++)
        {
            sum += (a[i] * (a[i] - 1)) / 2;
        }
        cout<<n * (n - 1) / 2 - sum<<endl;
        n++;
    }
    cout<<n<<endl;
}
int main()
{
    int n,m;
    cin>>n>>m;
    if(m < n - 1)
    {
        printf("Impossible\n");
        return 0;
    }
    for(int i = 2; i <= n; i++)
       edge.push_back({1,i});
    for(int i = 2; i <= min(n,1000); i++)
    {
        for(int j = i + 1; j <= min(n,1000); j++)
        {
            if(__gcd(i,j) == 1 && (int)edge.size() < m)
               edge.push_back({i,j});
        }
    }
    if((int)edge.size() < m)
    {
        printf("Impossible\n");
    }
    else
    {
        printf("Possible\n");
        for(int i = 0; i < m; i++)
            printf("%d %d\n",edge[i].first,edge[i].second);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值