1755 除数游戏 (找规律,数学:分解质因子/唯一分解定理)

题目描述:

1755 除数游戏

在除数游戏中,两人轮流行动,初始时有一个整数q,每次行动要写下一个整数,这个整数必须

是最近一次出现的整数的“强除数”。所谓一个整数的“强除数”是指除了1和该整数本身以外,可以

整除该整数的整数。

当游戏的某一方找不出符合以上条件的整数时,该方取得胜利,游戏结束。

假设游戏双方都采取最好的策略,给出初始数字。计算第一个写数字的人赢,还是第二个写数字

的人赢。

样例解释:

在样例一中,数字6的“强除数”是2和3。不管是写哪个数字,下一个人都赢了。
在样例二中,6是30的一个“强除数”。写下6后,接下来的过程同上。

输入

单组测试数据。
第一行,有1个整数q(1≤q≤10^13) 表示初始数字。

输出

共一行,如果第一个写数字的人赢,则输出1,否则输出2。

输入样例

6
30

输出样例

2
1

思路:

       本题不难,但是想复杂的话容易漏掉 n==1 的情况。

       刚开始想的是一般情况下只要能找到N的一个合数因子即第一人可赢,另外

或者N为素数也是第一人赢。其他情况一律第二人赢。但漏掉 N==1的情况。

      其实除了N只有两个素数因子且相乘等于N的情况是第二人赢外,其余情况

都是第一人赢 。

      尝试写了一下代码突然发现按照划掉部分思路写还是需要几个特判,还不如之前的思路呢。

代码实现(刚开始的思路):

 

#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
int fac[N],cnt;
int primeFac(LL x) {
  int num=0;
  for(LL i=2; i*i<=x; ++i) {
    if(x%i==0) {
      fac[++cnt]=i;
      while(x%i==0)x/=i,num++;
    }
  }
  if(x>1)num++,fac[++cnt]=x;
  return num;
}
int main() {


  LL n,ans;
  int tot;
  while(cin>>n) {
    cnt=0;
    ans=0;
    tot=primeFac(n);
    if(tot==1||tot==0) { //素数或者为1的情况
      cout<<1<<endl;
    } else {
      //否则,找一个合数因子
      for(LL i=2; i*i<=n; i++) {

        if(n%i==0) {
          if(primeFac(i)!=1) {
            ans=i;
            break;
          }
          if(primeFac(n/i)!=1) {
            ans=n/i;
            break;
          }
        }
      }
      if(ans) { //找到
        cout<<1<<endl;

      } else { //没找到
        cout<<2<<endl;
      }

    }
  }
  return 0;

}

THE END;

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值