翻硬币思路&&算法马拉松11 A翻硬币

本文探讨了如何通过最少次数的硬币翻转使所有硬币反面朝上,给出了解题思路及代码实现,并讨论了特殊情况下的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

有 n 个硬币,一开始全部正面朝上,每次可以翻转 k 个硬币( k 小于 n ),那么至少要 p 次翻转,才能让所有硬币反面朝上,求 p 的值。如果不能成功翻转则输出-1

Input
输入2个数:n,k (1 <= n <= 10^9, 1 <=  k <= 10^9)。
Output
输出翻转次数的最小值。
如果不能成功翻转则输出-1
Input示例
6 5
Output示例
6



在豆瓣的一个帖子里看到曾加老师的思路,就不把自己的拿出来丢人现眼了- -







附上按照这个思路写出来的代码:
#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(n%2)
        {
            if(k%2==0)
            {
                printf("-1\n");
                continue;
            }
            else
            {
                int f;
                f=(n+k-1)/k;
                if(f%2==0)
                   f++;
                printf("%d\n",f);
                continue;
            }
        }
        else
        {
            if(  (k%2==0)&&k>(n/2) && k<(n-1)  )
            {
                printf("3\n");
                continue;
            }
            else if(  (k%2)&&k>(n/2) && k<=(n-1)  )
            {
                int f;
                f=(n+n-k-1)/(n-k);
                if(f%2)
                    f++;
                printf("%d\n",f);
                continue;
            }
            else if(  (k%2==0)&& k<=(n/2)  )
            {
                int f;
                f=(n+k-1)/k;
                printf("%d\n",f);
                continue;
            }
            else if(  (k%2)&& k<=(n/2)  )
            {
                int f;
                f=(n+k-1)/k;
                if(f%2)
                    f++;
                printf("%d\n",f);
                continue;
            }
        }

    }
    return 0;
}



然而我最开始想的和另一种想法一样,即:


求不定方程
xy=(2y+1)n

的最小正整数解。由简单的初等数论知识,这个方程有整数解的必要条件是k和2n的最大公约数也是n的约数,即不允许k是偶数而n是奇数的情况。在有解的情况下,这个方程可以用扩展欧几里得算法来解。

之后@ dogther 发现了一个bug,即:
翻转的次数不一定是n的倍数;
举个例子  n=7  k=3 的时候,1-7编号 ;
第一次翻转1-3,第二次翻转3-6;第三次翻转3和6和7即可;

于是不能翻转n的奇数倍来解决;


暂时我就卡在这里了,想到也许能通过二分图来实现,试一试,什么时候能写了再更

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值