队内每周训练_2(补题)

A - Right-Coupled Numbers

在这里插入图片描述
思路

暴力去试就通过了。

#include<bits/stdc++.h>
using namespace std;
int n;

void solve(){
    scanf("%d",&n);
    for(int i=1;i<=sqrt(n);i++){
        if(n%i==0){
            int a=i,b=n/i;
            if(a>b) swap(a,b);
            if(a*2>=b){
                printf("1\n");
                return ;
            }
        }
    }
    printf("0\n");
}

int main(){
    int te;
    scanf("%d",&te);
    while(te--) solve();
}

G - August

在这里插入图片描述
在这里插入图片描述

思路

首先,这个图形左右对称,其次,上方图形为两个半圆。所以只需要计算右下方这块面积就可以了(计算左下方的也行)。
右下方的方程为 y = 2 b π ( a r c s i n x − a a − π 2 ) y=\frac{2b}{\pi}(arcsin\frac{x-a}{a}-\frac{\pi}{2}) y=π2b(arcsinaxa2π),在 [ 0 , 2 a ] [0,2a] [0,2a]积分,得 ∫ 0 2 a 2 b π ( a r c s i n x − a a − π 2 ) = 2 b π ∫ 0 2 a a r c s i n x − a a − ∫ 0 2 a b \int^{2a}_0\frac{2b}{\pi}(arcsin\frac{x-a}{a}-\frac{\pi}{2})=\frac{2b}{\pi}\int^{2a}_0arcsin\frac{x-a}{a}-\int^{2a}_0b 02aπ2b(arcsinaxa2π)=π2b02aarcsinaxa02ab.
其中 ∫ 0 2 a a r c s i n x − a a = ∫ − 1 1 a r c s i n x = 0 \int^{2a}_0arcsin\frac{x-a}{a}=\int^1_{-1}arcsinx=0 02aarcsinaxa=11arcsinx=0,所以面积为 2 a b 2ab 2ab
总面积为: 4 a b + a 2 π 4ab+a^2\pi 4ab+a2π

#include<bits/stdc++.h>
#define pi acos(-1)
using namespace std;
int a,b,te;
double ans=0,esp=1e-4;

void solve(){
    scanf("%d%d",&a,&b);
    ans=b*4*a;
    ans+=a*a*pi;
    printf("%f\n",ans);
}

int main(){
    scanf("%d",&te);
    while(te--) solve();
}

J - Goodbye

“Goodbye to the friends I’ve had, goodbye to my upstairs neighbor, goodbye to the kids downstairs, and anybody who lend me a favor.”

“Or, goodbye to the positive proper divisor?”

That game is popular these days. Two player take turns to choose a specific number and claim it. The player who takes the first turn chooses one positive proper divisor of given n. In the next rounds, player should choose one positive proper divisor (真因数) of the number claimed in the previous round. The player who can’t make a choice will win.

Formally, a positive proper divisor of n is a divisor of n, and it cannot be either 1 or n.

Now Chino is going to play this game with David. Chino always wants to win and meanwhile she wants to keep the chosen number as big as possible. If with the given n, Chino will win directly or fail anyway, you should also tell her.

Can you help Chino to choose her answer in the first round?

Input

The first line contains one integer T ( 1 ≤ T ≤ 1 0 3 ) T (1≤T≤10^3) T(1T103) denoting the count of testcases.

For each testcase, one line with one integer n ( 1 ≤ n ≤ 1 0 5 ) n (1≤n≤10^5) n(1n105) denoting the given n in one game.

Output

For each testcase, you should output the biggest choice, or 0 when Chino will win directly, or −1 when Chino will fail anyway.

Input

4
3
4
8
666

Output

0
-1
4
111

思路

对一个数进行质因数分解,设它有n个质因数(相同的因子出现多次的话,质因数数量也记录多次):

  1. 如果n==1,先手可以直接获胜。
  2. 如果n==2,先手必败。
  3. 其他情况,答案为最大的两个质因数之积。
#include<cstdio>
#include<cmath>
using namespace std;
int n,cnt,p[105];

void getPrime(int x){
    cnt=0;
    for(int i=2;i<=sqrt(x);i++)
        while(x%i==0)  p[cnt++]=i,x/=i;
    if(x>1)    p[cnt++]=x;
}

void solve(){
    scanf("%d",&n);
    getPrime(n);
    if(cnt==1)  puts("0");
    else if(cnt==2) puts("-1");
    else    printf("%d\n",p[cnt-1]*p[cnt-2]);
}

int main(){
    int te;
    scanf("%d",&te);
    while(te--) solve();
}

B - Make Numbers

在这里插入图片描述
在这里插入图片描述
题意

图片很模糊,题意为:输入四个小于10的整数,可以在数字之间添加 " + " , " − " , " ∗ " "+","-","*" "+","",""三种符号,也可以交换数字顺序,或者把两个、三个数字组合为一个数字。问,这些表达式可以产生多少种非负的结果?

#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
int a[4],ans;
set<int> st;

void calc2(int a,int b){
    st.insert(a+b); st.insert(a-b); st.insert(a*b);
}

void calc3(int a,int b,int c){
    st.insert(a+b+c);   st.insert(a+b-c);   st.insert(a+b*c);
    st.insert(a-b+c);   st.insert(a-b-c);   st.insert(a-b*c);
    st.insert(a*b+c);   st.insert(a*b-c);   st.insert(a*b*c);
}

void calc4(int a,int b,int c,int d){
    st.insert(a+b+c+d);    st.insert(a+b+c-d);    st.insert(a+b+c*d);
    st.insert(a+b-c+d);    st.insert(a+b-c-d);    st.insert(a+b-c*d);
    st.insert(a+b*c+d);    st.insert(a+b*c-d);    st.insert(a+b*c*d);

    st.insert(a-b+c+d);    st.insert(a-b+c-d);    st.insert(a-b+c*d);
    st.insert(a-b-c+d);    st.insert(a-b-c-d);    st.insert(a-b-c*d);
    st.insert(a-b*c+d);    st.insert(a-b*c-d);    st.insert(a-b*c*d);

    st.insert(a*b+c+d);    st.insert(a*b+c-d);    st.insert(a*b+c*d);
    st.insert(a*b-c+d);    st.insert(a*b-c-d);    st.insert(a*b-c*d);
    st.insert(a*b*c+d);    st.insert(a*b*c-d);    st.insert(a*b*c*d);
}

int main(){
    for(int i=0;i<4;i++)    scanf("%d",&a[i]);
    sort(a,a+4);
    do{
        calc2(a[0],a[1]*100+a[2]*10+a[3]);
        calc2(a[0]*10+a[1],a[2]*10+a[3]);
        calc2(a[0]*100+a[1]*10+a[2],a[3]);

        calc3(a[0],a[1],a[2]*10+a[3]);
        calc3(a[0],a[1]*10+a[2],a[3]);
        calc3(a[0]*10+a[1],a[2],a[3]);

        calc4(a[0],a[1],a[2],a[3]);
    }while(next_permutation(a,a+4));
    for(int e : st) if(e>=0)    ans++;
    printf("%d",ans);
}

基本上照搬了别人的代码,每个 c a l c calc calc函数只管当前顺序下的组合,不交换数字顺序。 c a l c calc calc函数内部直接列举出所有的计算方法。
注意最后只统计答案非负的数量。

E - Optimization for UltraNet

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
思路

把原问题转为二分判定存在,就可以得到权值最小的边。之后建图,对于每条边,设它连接的两个结点分别为u和v,权值为w,则它对答案的贡献为 S i z e ( u ) × S i z e ( v ) × w Size(u)\times Size(v)\times w Size(u)×Size(v)×w S i z e ( u ) Size(u) Size(u)代表u所在的连通分量的大小。从最小生成树的最短边开始,每次计算最短的边,计算之后删掉这条边。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e4+5,Emaxn=1e6+5;
struct N{int u,v,w;}e[Emaxn];
int head[maxn],ver[Emaxn],edge[Emaxn],Next[Emaxn],from[Emaxn],tot;
int n,m,fa[maxn],ans,vis[maxn],l,r;

void add(int u,int v,int w){ver[++tot]=v,edge[tot]=w,from[tot]=u,Next[tot]=head[u],head[u]=tot;}
int get(int x){return fa[x]==0?x:fa[x]=get(fa[x]);}
bool cmp(N &a,N &b){return a.w<b.w;}

bool judge(int mid,int build=0){
    memset(fa,0,sizeof(fa));
    int cnt=n;
    for(int i=mid;i<m;i++){
        int x=get(e[i].u),y=get(e[i].v);
        if(x==y)    continue;
        if(build)   add(e[i].u,e[i].v,e[i].w),add(e[i].v,e[i].u,e[i].w);
        fa[x]=y;    cnt--;
        if(cnt==1)  return true;
    }
    return cnt==1;
}

int getSize(int x,int v){
    int ret=1;  vis[x]=1;
    for(int i=head[x];i;i=Next[i])
        if(!vis[ver[i]]&&edge[i]>v)    ret+=getSize(ver[i],v);
    return ret;
}

signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=0;i<m;i++)
        scanf("%lld%lld%lld",&e[i].u,&e[i].v,&e[i].w);
    sort(e,e+m,cmp);
    l=0,r=m-1;
    while(l<r){
        int mid=(l+r+1)/2;
        if(judge(mid))  l=mid;  else    r=mid-1;
    }
    for(int i=1;i<=tot;i++){
        memset(vis,0,sizeof(vis));
        int a=getSize(from[i],edge[i]),b=getSize(ver[i],edge[i]);
        ans+=a*b*edge[i];
    }
    printf("%lld\n",ans/2);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

m0_51864047

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

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

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

打赏作者

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

抵扣说明:

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

余额充值