输入一个初始位置x_0,范围在1到1,000,000,006
输出小易最少需要使用神秘力量的次数,如果使用次数使用完还没找到贝壳,则输出-1
125000000
1
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner in = new Scanner(System.in); long x=in.nextLong(); if(x==0) System.out.println("1"); else System.out.println(gettimes(x)); } public static long gettimes(long x) { long temp=x; for(int i=1;i<=300000;i++) { temp=(temp*2+1)%1000000007; if(temp==0) { for(int j=0;j<=(i/2);j++) { if((i-j*2)%3==0) { return (i+j)/3; } } } } return -1L; } }
import java.util.Scanner; public clas***ain { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); long x0 = scanner.nextLong(); long m = 1000000007;//取模的值 long s = 100000; //神秘力量使用的次数 long[] begin = new long[3]; //f(x) = 4x+3 执行3次 //3次的取值 begin[0] = x0; begin[1] = (4 * begin[0] + 3) % m; begin[2] = (4 * begin[1] + 3) % m; long minStep = s; long cur = 0; int step = 0; //执行的步数 for (int i = 0; i < 3; i++) { cur = begin[i]; step = i; while (cur != 0 && step < minStep) { cur = (8 * cur + 7) % m; //g(x) = 8x+7 执行 step++; } minStep = minStep < step ? minStep : step; } if (minStep < s) { //如果执行步长没有超过s输出最小步长 System.out.println(minStep); } else {//超过返回-1 System.out.println(-1); } } }
参考@Leori 的思路,4x+3和8x+7执行顺序可以交换,做三次4x+3等于做两次8x+7
参考一个老哥的答案 import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String line = scanner.nextLine(); long x = Long.parseLong(line); System.out.println(min(x)); } public static long min(long x) { //4x + 3和8x + 7可以拆成2x + 1; long count = 0; long goal = 1000000007; while (count <= 300000) { //防止溢出,每次都取余数 x = ((x << 1) + 1) % goal; count ++; if (count == 1)continue; if (x == 0)break; } if (count > 300000) { return -1; } //这个式子的意思是,count = 2时,res = 1,count = 3时,res = 1. //以此类推是正确的可以把一个数拆成最小的2和3的组合个数。 //虽然我也不知道为什么。count = 1时是不行的。 long res = (count + 2)/3; if (res > 100000) { return -1; }else { return res; } // } }
速度不快但是思路简单。
4x + 3等于做了两次2x + 1, 8x + 7做了三次。
从起点开始令x0 = 2*x0 + 1,统计做了多少次2x + 1后模1000000007等于0
//基于 陈丽丰 的思路实现: import java.util.*; public class Main { private static long molecole = 1000000007; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int count=0; long x_0=sc.nextInt(); long x_1=x_0*4+3; long x_2=x_1*4+3; if(g(x_0,++count)||g(x_1,++count)||g(x_2,++count)){ }else{ System.out.println(-1); } } public static boolean g(long x,int count) { boolean result=false; while (count <= 100_000){ long temp=8*x+7; if(temp%molecole==0){ result=true; System.out.println(count); break; }else { x=temp%molecole; count++; } } return result; } }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); System.out.println(fun(n)); sc.close(); } public static int fun(int n){ int mod = 1000000007; int times = 4; int ans = 100001; for(int i = 0; i < 300000; i++){ int x = (int)(((long)n*times + times -1)%mod); if(x==0){ ans = (i+2)/3+((i+2)%3!=0?1:0); break; } times = (times << 1) % mod; } return ans > 100000 ? -1 : ans; } }