对于一个由 0..n 的所有数按升序组成的序列,我们要进行一些筛选,每次我们丢弃去当前所有数字中第奇数位个的数。重复这一过程直到最后剩下一个数。请求出最后剩下的数字。
数据范围: ,本题有多组输入
//數學規律 import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in) ; while(sc.hasNext()){ int n=sc.nextInt(); int m=0; int sum=0; while(n>1) { n=n/2; m++; sum=sum+(int)Math.pow(2, m-1); } System.out.println(sum); } } }
public static void main(String[] args) { int size = 5000; LinkedList<Integer> integers = intToLList(size); LinkedList<Integer> integers2 = new LinkedList<>(); while (integers.size() != 1) { for (int i = 0; i < integers.size(); i++) { if ((i+1)%2 != 0) { integers2.add(integers.get(i)); } } for (Integer integer : integers2) { integers.remove(integer); } } System.out.println(integers.get(0)); } private static LinkedList<Integer> intToLList(int n) { LinkedList<Integer> integers = new LinkedList<>(); for (int i = 0; i <= n; i++) { integers.add(i); } return integers; }
以 n = 37 为例,即 0 ~ 37
time = 1
,开始位置 base = 0
,每次位置新增为 up=2
,删除的值为:time = 2
,开始位置 base = 1
,每次位置新增为 up = 4
,删除的值为:time = 3
,开始位置 base = 3
,每次位置新增 up = 8
,删除的值为:import java.util.Scanner; /** * @author GJXAIOU */ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int inputValue = scanner.nextInt(); if (inputValue == 0) { System.out.println(0); } int[] values = new int[inputValue + 1]; for (int i = 0; i < values.length; i++) { values[i] = i; } // time 表示第几次运行删除 int time = 1; // 每次删除的第一个数 int base = 0; // 每次删除时候递增的间隔 int up = 2; // 还有多少值没有检查替换 int left = values.length; while (left > 1) { for (int i = base; i < values.length; i += up) { values[i] = 0; left--; } base = (int) (base + Math.pow(2, time - 1)); // 进行下一次 time++; // 每次运行删除间隔都是 2 的倍数 up *= 2; } for (int i = 0; i < values.length; i++) { if (values[i] != 0) { System.out.println(values[i]); } } } } }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ int n = sc.nextInt(); List<Integer> list = new ArrayList<Integer>(); for(int i=0;i<=n;i++) list.add(i); while(list.size() > 1){ for(int i=0; i < list.size();i++) list.remove(i); } System.out.println(list.get(0)); } } }
import java.util.Scanner; // 找规律每次删除后的第一个数为2^times - 1然后算出 times 即可 public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int n = scanner.nextInt(); int total = n + 1; int times = 0; while (total != 1) { total /= 2; times++; } System.out.println(String.format("%.0f", Math.pow(2, times) - 1)); } } }
//一开始以为是约瑟夫环问题,后来自己试了连个例子,不太像。 //每次去除奇数位只留下原来的个数的一半,m次后只剩下一个数 //假设将剩下的数看做1,则在原来的序列中他是2^m,m=logn //不知道说的明白不,贴出来给大家一个思路吧
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner in =new Scanner(System.in);
while(in.hasNext()){
int n=in.nextInt();
int m = (int)(Math.log(n)/Math.log(2));
System.out.println((int)(Math.pow(2,m))-1);
}
}
}
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input=new Scanner(System.in); while(input.hasNext()) { int n=input.nextInt(); int len=0; while(n>1) { n=n>>1; len++; } System.out.println((1<<len)-1); } input.close(); } }
求大神解疑惑。本地运行答案都对,为什么在这里却没有输出。 import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); double tmp = Math.log(n)/Math.log(2); double count = Math.floor(tmp); System.out.println((int)Math.pow(2,count)-1); } }
import java.util.*;
public class Main { public static void main(String[] args){ Scanner in = new Scanner(System.in); while (in.hasNext()){ int n = in.nextInt(); List<Integer> list = new ArrayList<Integer>(); for (int i = 0; i <= n; i++) list.add(i); while (list.size() > 1){ for (int j = 0; j < list.size(); j++) list.remove(j); } System.out.println(list.get(0)); } } }
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner in=new Scanner(System.in); while(in.hasNext()){ int n =in.nextInt(); int num=0; int s=1; for(int i=0;num<n;i++ ){ num=2*s-2; s*=2; } System.out.println(num/2); } } }
学会找规律
import java.util.*; public class Main { public static void main(String[] args){ Scanner sc=new Scanner(System.in); while(sc.hasNext()){ int n = sc.nextInt(); ArrayList<Integer> list = new ArrayList<Integer>(); for(int i=0;i<=n;i++){ list.add(i); } while(list.size()>1){ for(int i=0;i<list.size();i=i+1){//注意不是i+2,因为删除了右边的前移 list.remove(i); } } System.out.println(list.get(0)); } } }
用一个辅助的数组,1代表死,2代表活。不断地挑出筛选过的数组,不断递归。 import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while(in.hasNext()){ int n = in.nextInt(); int[] arr = new int[n+1]; //初始化数组 for(int i=0;i<n+1;i++){ arr[i] = i; } while(arr.length!=1){ arr=getNewArr(arr); } System.out.println(arr[0]); } } public static int[] getNewArr(int[] arr){ if(arr == null){ return null; } //标志数组,初始化为0,1为死,2为活 int[] vice = new int[arr.length]; int[] result = new int[arr.length/2]; for(int i=0;i<vice.length;i++){ //如果是双数位,令他死置为1 if(i%2==0){ vice[i] = 1; }else{ vice[i] = 2; } } //result数组的标志 int num = 0; for(int i=0;i<arr.length;i++){ if(vice[i] == 2){ result[num++] = arr[i]; } } return result; } }
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt(); List<Integer> list = new ArrayList<Integer>(); for (int i = 0; i <= n; i ++ ) list.add(i); while (list.size() != 1) { // 从0开始list移除一次,i再加一次,i始终指向奇数位 for (int i = 0; i < list.size(); i = i + 1) list.remove(i); } System.out.println(list.get(0)); } } }