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;
}