题目描述
A想玩个游戏,游戏规则是,有n个人,编号从1-n,一字排开,站在奇数位置的人淘汰,剩下的人再一字排开,站在奇数位置的人淘汰,以此重复几次,最后只剩最后一个人,问最后一个人的编号是多少?
输入
输入一个正整数n(2≤n≤1e100);
输出
输出一个整数,代表最后剩余的编号。
样例输入
12
样例输出
8

首先注意到数据范围特别大,需要用字符串读入

每次淘汰完一轮后剩下的第一个数总是2的倍数,有这个规律,利用大数乘法和大数除法解决 

 1 #include<stdio.h>
2
#include<string.h> 3 #include<math.h> 4 #include<iostream> 5 #include<algorithm> 6 #define ll long long 7 using namespace std; 8 #define N 1010 9 char str[N]; 10 int arr[N]; 11 int num[N]; 12 int main() 13 { 14 int i; 15 while(scanf("%s",str)!=EOF) 16 { 17 int len=strlen(str); 18 for(i=0;i<len;i++) 19 arr[i]=str[i]-'0'; 20 int m=0,flag=0; 21 num[0]=1; 22 while((arr[len-1]!=1)||(flag!=0))//循环只剩下一个人时结束 23 { 24 for(int i=0;i<len;i++) 25 { 26 if(arr[i]==0) continue; 27 if(arr[i]%2==0) 28 { 29 arr[i]=arr[i]/2; 30 } 31 else 32 { 33 if(i==len-1) 34 arr[i]=arr[i]/2; 35 else 36 { 37 arr[i]=arr[i]/2; 38 arr[i+1]+=10; 39 } 40 } 41 }
42 for(int i=2; i<=2; i++)//完全套用大数阶乘的代码 43 { 44 for(int j=0; j<=m; j++) 45 num[j]=num[j]*i; 46 for(int k=1; k<=m; k++) 47 { 48 num[k]+=num[k-1]/10; 49 num[k-1]=num[k-1]%10;//注意和上一个的顺序 50 } 51 while(num[m]>10) 52 { 53 num[m+1]=num[m]/10; 54 num[m]%=10; 55 m++; 56 } 57 } 58 flag=0; 59 for(int i=0;i<len-1;i++) 60 { 61 if(arr[i]!=0) 62 flag=1; 63 } 64 } 65 for(int i=m; i>=0; i--) 66 printf("%d",num[i]); 67 printf("\n"); 68 } 69 return 0; 70 }