对于一个由 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));
}
}
}