fjnu18级第一次友谊赛

D-地虎侠

1 1 1堆石子有 n n n个,两人轮流取.先取者第 1 1 1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的 2 2 2倍。取完者胜.先取者负输出" S e c o n d Second Second w i n win win“.先取者胜输出” F i r s t First First w i n win win“.
I n p u t Input Input
输入有多组.每组第 1 1 1行是 2 < = n < 2 31 2<=n<2^{31} 2<=n<231 n = 0 n=0 n=0退出.
O u t p u t Output Output
先取者负输出” S e c o n d Second Second w i n win win“. 先取者胜输出” F i r s t First First w i n win win".
S a m p l e I n p u t Sample Input SampleInput
2 2 2
13 13 13
10000 10000 10000
0 0 0
S a m p l e O u t p u t Sample Output SampleOutput
S e c o n d w i n Second win Secondwin
S e c o n d w i n Second win Secondwin
F i r s t w i n First win Firstwin

在这里插入图片描述
首先全文无干货,全是瞎几把写,想看干货可以移步斐波那契博弈

题目分析:想了几分钟没思路,也许是规律题,直接开始打表(遇事不决先打表?)

n2345678
\SSFSFFS

在这里插入图片描述
这里 F F F 表示先手胜利, S S S 表示后手胜利。
刚开始看没有什么规律,感觉就是乱赢的…之后注意到后手 ( S ) (S) (S)赢时 n n n似乎满足斐波那契数列 ( 2 , 3 , 5 , 8 ) (2,3,5,8) 2,3,5,8然后为了验证继续打表到 13 13 13

910111213
FFFFS

在这里插入图片描述
搏一搏单车变摩托…然后就一发 A C AC AC

贴一下我 A C AC AC的代码:(脑抽一开始写斐波那契数列就顺手写矩阵快速幂模板,后面懒得改了)

#include<stdio.h>
#include<string.h>

struct Mat {
  long long mat[3][3];
};

Mat Mult(Mat A, Mat B) {
  Mat ans1;
  memset(ans1.mat, 0, sizeof ans1.mat);
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
      for (int k = 0; k < 2; k++) {
        ans1.mat[i][j] += (A.mat[i][k] * B.mat[k][j]);
        ans1.mat[i][j];
      }
    }
  }
  return ans1;
}

Mat Pow(Mat A, int n) {
  Mat ans2;
  memset(ans2.mat, 0, sizeof ans2.mat);
  for (int i = 0; i < 2; i++)
    ans2.mat[i][i] = 1;
  while (n) {
    if (n % 2)
      ans2 = Mult(ans2, A);
    A = Mult(A, A);
    n /= 2;
  }
  return ans2;
}

int main() {
  long long n, num, x = 0, y = 1;

  while (scanf("%lld", &n) != EOF) {
    if (n == 0)
      break;
    int i, a = 1;
    Mat ans;
    for (i = 2; i <= 50; i++) {    //2^31=2147483647 斐波那契数列在第47项就已经超过这个数了 
      ans.mat[0][0] = 1;
      ans.mat[0][1] = 1;
      ans.mat[1][0] = 1;
      ans.mat[1][1] = 0;
      ans = Pow(ans, i - 1);
      num = ans.mat[0][0] * y + ans.mat[0][1] * x;
      if (num == n) {
        printf("Second win\n");
        a = 0;
      }
    }
    if (a)
      printf("First win\n");
  }
  return 0;
}

其实直接打斐波那契数列表,然后一一对应就好了。

#include<stdio.h>

int main()
{
	long long i,n,a[50];
	a[0]=0;a[1]=1;
	for(i=2;i<=48;i++)
	a[i]=a[i-1]+a[i-2];
	
	while(scanf("%lld",&n),n){
		int flag=1;
		for(i=2;i<=48;i++){
			if(n==a[i]){
				printf("Second win\n");
					flag=0;
			}
		}
		if(flag)
		printf("First win\n");
	}
	return 0;
}

恭喜 F L S FLS FLS让我喜提一篇博客。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值