Educational Codeforces Round 89 (Rated for Div. 2) A D 题

复工第一场CF,给我整的很难受

Educational Codeforces Round 89 (Rated for Div. 2)

A题

题意

T组输入,每组给出两个数字 $a $, \(b\) ,分别表示两种原材料的数量,使用 1 个 \(a\) 和 2 个 \(b\) 可以制造玩具 A , 使用 2 个 \(b\) 和 1 个 \(a\) 可以制造玩具 B ,每个玩具都可以卖 1 元,问最多可以赚多少钱?

思路

我们假设 a < b。

想来想去还是用的高中学的不等式的方法,设玩具 A 制造了 \(x\) 个,玩具 B 制造了 \(y\) 个,列不等式:

\[y<=-\frac{1}{2} x+\frac{a}{2}\\y<=-2x+b \]

\(y=-x+z\)\(z\) 的最大值。

如果\(2*a<=b\) 那么在\((a,0)\)处取的最大值,否则在两直线交点\((\frac{2*b-a}{3},相应的y)\)处取得最大值。

第二种情况求出交点横坐标 \(x\) 之后,在求纵坐标 \(y\) 时,注意不能直接代入直线,因为横坐标\(x\)

可能是经过取整的,所以代入可能会不再直线上,要通过两个不等式求最大的 \(y\)

代码

#include<bits/stdc++.h>
#define pb push_back
const int N=1e5+10;
const int inf=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;

int a,b;
int get(int x)
{
    int m=b-2*x;
    int n=(a-x)/2;
    return min(m,n);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&a,&b);
        if(a>b) swap(a,b);
        if(a*2<=b) printf("%d\n",a);
        else
        {
            int x=(2*b-a)/3;
            printf("%d\n",x+get(x));
        }
    }
    return 0;
}

D题

题意

给出 \(n\) 个数字,对于每个数字 \(x\) 求出两个数字 \(d_1,d_2\) ,满足\(gcd(d_1+d_2,x)==1\),\(x\%d_1==0\),\(x\%d_2==0\)。如果不存在输出两个 -1 。

思路

\(x\) 进行质因数分解后:\(x=p_1^{k_1}*p_2^{k_2}*···*p_{n-1}^{k_n-1}*p_n^{k_n}\)

\(d_1=p_1^{k_1},d_2=x/d_1\)

此时满足:

\((d_1+d_2)\%p_1!=0\)

\((d_1+d_2)\%p_2!=0\)

......

\((d_1+d_2)\%p_n!=0\)

所以我们只需求出 \(x\) 的最小的质因数,使用欧拉筛素数。

代码

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=5e5+10;
const int inf=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;

int arr[N],a[N],b[N];
int vis[N*20],pri[N*20],tot;
void solve(int n)
{
    for(int i=2; i<=n; i++)
    {
        if(!vis[i])
            pri[++tot]=i;
        for(int j=1; j<=tot; j++)
        {
            if(i*pri[j]>n)
                break;
            vis[i*pri[j]]=pri[j];//纪录最小的素因子
            if(i%pri[j]==0)
                break;
        }
    }
}

int main()
{
    solve(N*20);
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        int x;
        scanf("%d",&x);
        if(!vis[x])
            a[i]=b[i]=-1;
        else
        {
            int num=1;
            int tmp=vis[x];
            while(x%tmp==0)
            {
                num*=tmp;
                x/=tmp;
            }
            if(x==1)
                a[i]=b[i]=-1;
            else
            {
                a[i]=x;
                b[i]=num;
            }
        }
    }
    for(int i=1; i<=n; i++)
        printf("%d ",a[i]);
    printf("\n");
    for(int i=1; i<=n; i++)
        printf("%d ",b[i]);
    printf("\n");
    return 0;
}
posted @ 2020-07-11 16:07  Valk3  阅读(63)  评论(0编辑  收藏  举报