10.29monisai

10.29摸尼塞

  • 爆蛋了,对拍写错了, 难怪拍了一万发都没问题,可得注意fc里面的文件名。

T1

  • 题目描述

    约翰正在学习数论,想请你帮帮他:有一个正整数 k k k。请你判断是否存在正整数 n n n ,使得 n 2 n^2 n2 k k k 的倍数,且 n n n 不是 k k k 的倍数。

    如果存在,请输出最小的 n n n。不存在则输出 − 1 -1 1

  • 数学题。 n n n不是 k k k的倍数,但 n 2 n ^ 2 n2 k k k的倍数,那么暴力就很简单,枚举k的倍数,看是否有一个能开二次方的数,(能拿50分);

  • 正解首先要想到质因数分解,分别将 n n n n 2 n ^ 2 n2质因数分解,显然,两数的质因数种类应相同,且同一质因数 n 2 n ^ 2 n2的个数是 n n n的二倍,

n = p 1 a 1 × p 2 a 2 × . . . × p t a t n = p1^{a1} \times p2 ^{a2} \times ...\times pt ^{at} n=p1a1×p2a2×...×ptat

n 2 = ( p 1 2 × a 1 × p 2 2 × a 2 × . . . × p t 2 × a t ) n^2 = (p1^{2\times a1} \times p2 ^{2\times a2} \times ...\times pt ^{2\times at}) n2=(p12×a1×p22×a2×...×pt2×at)

  • 那么,如果 n 2 n ^ 2 n2是k的倍数,就说明 n 2 n ^ 2 n2的质因数包含了 k k k的质因数,同理,不包含则说明n中质因数不包含k中质因数,又因n 与 n 2 n ^ 2 n2的质因数种类相同,那么差别只有数量大小,所以,我们可以直接分解k,得到每一个质因数的个数,并对于每个个数除2,构造出一个n.由此可得,当每一位都为1时,就是不存在的情况。

    long long t = k;
    for(int i = 2;(i - 1) * (i - 1) <= t; i++){//把最后大于一位的情况枚举到
        if(k % i == 0){//i必为质数,因为合数的情况也被之前的质数分解为质数乘质数
            int num= 0;
            while(k % i == 0){
                k /= i;
                num++;//统计质因数个数
            }
            for(int j = 1;j <= (num + 1) / 2; j++)
                n *= i;
        }
        if(k == 1) break;
    }
    if(t == n) printf("-1");
    else{
        if(k == 1) printf("%lld",n);//判断分解完是否剩余质数
        else printf("%lld",n * k);
    } 
    
  • 所以,考试时,要记住一类题常考的思路,可大大节省效率,思路也不易跑偏。

T2

  • 具体地,有 n n n个带权点,每个点有一个点权。还有 m m m条无向边。当删一个点时,需要扫描所有与之相连的边,计算这些边的点的点权之和。删掉后这个点与和它连接的边都要删除。求出删除所有点的最小代价。
  • 这一题也是性质探索,我们如果按照题目意思思考每个点,很复杂,因为一个点的改变会改变周围的点的情况。不妨换个思路——从边上考虑,总之,最后所有边都会被删除,而且,删掉一个边后并不影响其他边,也就是说,每条边都产生贡献,所以,对于每一条边在两端端点中取较小值,就是最终答案。
  • 这样删除不会出现环,理由:不妨设有三个点,a , b , c,如果将无向边改为有向边,且从较大数指向较小数,有环的情况就必须满足: w [ a ] < w [ b ] w[a] < w[b] w[a]<w[b] && w [ b ] < w [ c ] w[b] < w[c] w[b]<w[c] && w [ c ] < w [ a ] w[c] < w[a] w[c]<w[a],显然不成立。对于三数相同的情况,就让后出现指向先出现的,即可解决;
for(int i = 1;i <= n; i++) scanf("%d",&w[i]);
long long ans = 0,a,b;
for(int i =1 ; i <= m; i++){
    scanf("%d%d",&a , &b);
    ans += min(w[a] , w[b]);
}
printf("%lld",ans);
  • 当一种思考角度比较复杂时,要尝试不同的角度,会有新的收获。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值