历年题目

2012年

微生物繁殖
假设有两种微生物 X 和 Y
X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍)。
一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y。
现在已知有新出生的 X=10, Y=89,求60分钟后Y的数目。
如果X=10,Y=90  呢?
本题的要求就是写出这两种初始条件下,60分钟后Y的数目。
题目的结果令你震惊吗?这不是简单的数字游戏!真实的生物圈有着同样脆弱的性质!也许因为你消灭的那只 Y 就是最终导致 Y 种群灭绝的最后一根稻草!
请忍住悲伤,把答案写在“解答.txt”中,不要写在这里!
 
 
思路:我们可以先看一个新出生的X,在0.5、1.5、2.5……这些时刻会吃掉1个Y,在[0,1]、[1,2]、[2,3]……这些长度为1的区间内都会吃掉1个Y,那么我们不妨就都往前或往后挪0.5分钟,也就是直接算一个X每隔1分钟都会吃掉1个Y。因为半分钟不好处理,所以我们可以把时间整体上都乘2,那么就相当于每2分钟Y被吃掉X个,每6分钟X数目加倍,每4分钟Y数目加倍,还有一点就是当Y减少到小于等于0时就被吃完了。

 

答案:0 94371840
 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <cstring>
 7 #include <stdio.h>
 8 #define lowbit(x) x&(-x)
 9 
10 using namespace std;
11 const int maxn=1e5+10;
12 typedef long long ll;
13 
14 int main(){
15     ios::sync_with_stdio(0);
16     int x,y;
17     cin>>x>>y;
18     for(int i=1;i<=120;i++){
19         if(y<=0){
20             y=0;
21             break;
22         }else{
23             if(i%2==1)
24                 y-=x;
25             if(i%4==0)
26                 y=y*2;
27             if(i%6==0){
28                 x=2*x;
29             }
30         }
31     }
32     cout<<y<<endl;
33     return 0;
34 }

 

古堡算式
福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:
ABCDE * ? = EDCBA
他对华生说:“ABCDE应该代表不同的数字,问号也代表某个数字!”
华生:“我猜也是!”
于是,两人沉默了好久,还是没有算出合适的结果来。
请你利用计算机的优势,找到破解的答案。
把 ABCDE 所代表的数字写出来。
答案写在“解答.txt”中,不要写在这里!
 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <cstring>
 7 #include <stdio.h>
 8 #define lowbit(x) x&(-x)
 9 
10 using namespace std;
11 const int maxn=1e5+10;
12 typedef long long ll;
13 
14 int main(){
15     ios::sync_with_stdio(0);
16     for(int a=1;a<=9;a++){
17         for(int b=0;b<=9;b++){
18                 if(b==a)
19                     continue;  //abcde代表不同数字
20             for(int c=0;c<=9;c++){
21                 if(c==a||c==b)
22                     continue;
23                 for(int d=0;d<=9;d++){
24                     if(d==a||d==b||d==c)
25                         continue;
26                     for(int e=1;e<=9;e++){
27                         if(e==a||e==b||e==c||e==d)
28                             continue;
29                         for(int f=2;f<=9;f++){  //edcba 反过来
30                             if((a*10000+b*1000+c*100+d*10+e)*f==(e*10000+d*1000+c*100+b*10+a))
31                                 cout<<a*10000+b*1000+c*100+d*10+e<<endl;
32                         }
33                     }
34                 }
35             }
36         }
37     }
38     return 0;
39 }

 

海盗比酒量
有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了。再打开一瓶酒平分,又有倒下的,再次重复...... 直到开了第4瓶酒,坐着的已经所剩无几,海盗船长也在其中。当第4瓶酒平分喝下后,大家都倒下了。
等船长醒来,发现海盗船搁浅了。他在航海日志中写到:“......昨天,我正好喝了一瓶.......奉劝大家,开船不喝酒,喝酒别开船......”
请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人。
如果有多个可能的答案,请列出所有答案,每个答案占一行。
格式是:人数,人数,...
例如,有一种可能是:20,5,4,2,0
答案写在“解答.txt”中,不要写在这里!
--->枚举四轮的人数,1/a+1/b+1/c+1/d=1,变形一下就是bcd+acd+abd+abc=abcd。
 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <cstring>
 7 #include <stdio.h>
 8 #define lowbit(x) x&(-x)
 9 
10 using namespace std;
11 const int maxn=1e5+10;
12 typedef long long ll;
13 
14 int main(){
15     ios::sync_with_stdio(0);
16     for(int a=20;a>=1;a--){
17         for(int b=a-1;b>=1;b--){
18             for(int c=b-1;c>=1;c--){
19                 for(int d=c-1;d>=1;d--){
20                     if(b*c*d+a*c*d+a*b*d+a*b*c==a*b*c*d){
21                         cout<<a<<","<<b<<","<<c<<","<<d<<",0"<<endl;
22                     }
23                 }
24             }
25         }
26     }
27     return 0;
28 }
 
奇怪的比赛
某电视台举办了低碳生活大奖赛。题目的计分规则相当奇怪:
每位选手需要回答10个问题(其编号为1到10),越后面越有难度。答对的,当前分数翻倍;答错了则扣掉与题号相同的分数(选手必须回答问题,不回答按错误处理)。
每位选手都有一个起步的分数为10分。
某获胜选手最终得分刚好是100分,如果不让你看比赛过程,你能推断出他(她)哪个题目答对了,哪个题目答错了吗?
如果把答对的记为1,答错的记为0,则10个题目的回答情况可以用仅含有1和0的串来表示。例如:0010110011就是可能的情况。
你的任务是算出所有可能情况。每个答案占一行。
答案写在“解答.txt”中,不要写在这里!
 
 
思路:dfs,用一个数组存情况,注意数组记录情况的那一步一定要在进下一步dfs前。
 
 
 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <cstring>
 7 #include <stdio.h>
 8 #define lowbit(x) x&(-x)
 9 
10 using namespace std;
11 const int maxn=1e5+10;
12 typedef long long ll;
13 int a[15]={0};
14 void dfs(int n,int score){
15     if(n==11){
16         if(score==100){
17             for(int i=1;i<11;i++){
18                 cout<<a[i];
19             }
20             cout<<endl;
21             return;
22         }
23         return ;
24     }
25     a[n]=0;
26     dfs(n+1,score-n);
27     a[n]=1;
28     dfs(n+1,score*2);
29 }
30 
31 int main(){
32     ios::sync_with_stdio(0);
33     dfs(1,10);
34     return 0;
35 }

 

 
转方阵
对一个方阵转置,就是把原来的行号变列号,原来的列号变行号
例如,如下的方阵:
 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15 16
转置后变为:
 1  5  9 13
 2  6 10 14
 3  7 11 15
 4  8 12 16
但,如果是对该方阵顺时针旋转(不是转置),却是如下结果:
13  9  5  1
14 10  6  2
15 11  7  3
16 12  8  4
下面的代码实现的功能就是要把一个方阵顺时针旋转。
 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <cstring>
 7 #include <stdio.h>
 8 #define lowbit(x) x&(-x)
 9 
10 using namespace std;
11 const int maxn=1e5+10;
12 typedef long long ll;
13 void rotate(int *x,int rank){
14     int*  y=(int *)malloc(int(*)rank*rank);
15     for(int i=0;i<rank*rank;i++){
16         y[rank*(rank-i%rank)+(rank-i%rank-1)]=x[i];
17     }
18     for(int i=0;i<rank*rank;i++){
19         x[i]=y[i];
20     }
21 }
22 
23 int main(){
24     ios::sync_with_stdio(0);
25     int x[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
26     int rank=4;
27     rotate(&x[0][0],rank);
28     for(int i=0;i<rank;i++){
29         for(int j=0;j<rank;j++){
30             printf("%4d",x[i][j]);
31         }
32         printf("\n");
33     }
34     return 0;
35 }
大数乘法
对于32位字长的机器,大约超过20亿,用int类型就无法表示了,我们可以选择int64类型,但无论怎样扩展,固定的整数类型总是有表达的极限!如果对超级大整数进行精确运算呢?一个简单的办法是:仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法”。
如图【1.jpg】表示了分块乘法的原理。可以把大数分成多段(此处为2段)小数,然后用小数的多次运算组合表示一个大数。可以根据int的承载能力规定小块的大小,比如要把int分成2段,则小块可取10000为上限值。注意,小块在进行纵向累加后,需要进行进位校正。
以下代码示意了分块乘法的原理(乘数、被乘数都分为2段)。
 1 void bigmul(int x, int y, int r[])
 2 {
 3     int base = 10000;
 4     int x2 = x / base;
 5     int x1 = x % base; 
 6     int y2 = y / base;
 7     int y1 = y % base; 
 8 
 9     int n1 = x1 * y1; 
10     int n2 = x1 * y2;
11     int n3 = x2 * y1;
12     int n4 = x2 * y2;
13 
14     r[3] = n1 % base;
15     r[2] = n1 / base + n2 % base + n3 % base;
16     r[1] = n2/base+n3/base+n4%base; // 填空
17     r[0] = n4 / base;
18     
19     r[1] += r[2]/base;  // 填空
20     r[2] = r[2] % base;
21     r[0] += r[1] / base;
22     r[1] = r[1] % base;
23 }
24 
25 
26 int main(int argc, char* argv[])
27 {
28     int x[] = {0,0,0,0};
29 
30     bigmul(87654321, 12345678, x);
31 
32     printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]);
33 
34     return 0;
35 }

  

 
放棋子
今有 6 x 6 的棋盘格。其中某些格子已经预先放好了棋子。现在要再放上去一些,使得:每行每列都正好有3颗棋子。
我们希望推算出所有可能的放法。下面的代码就实现了这个功能。
初始数组中,“1”表示放有棋子,“0”表示空白。 
 
  1 int N = 0;
  2 
  3 bool CheckStoneNum(int x[][6])
  4 {
  5     for(int k=0; k<6; k++)
  6     {
  7         int NumRow = 0;
  8         int NumCol = 0;
  9         for(int i=0; i<6; i++)
 10         {
 11             if(x[k][i]) NumRow++;
 12             if(x[i][k]) NumCol++;
 13         }
 14         if(NumRow!=3||NumCol!=3) return false;  // 填空
 15     }
 16     return true;
 17 }
 18 
 19 int GetRowStoneNum(int x[][6], int r)
 20 {
 21     int sum = 0;
 22     for(int i=0; i<6; i++)     if(x[r][i]) sum++;
 23     return sum;
 24 }
 25 
 26 int GetColStoneNum(int x[][6], int c)
 27 {
 28     int sum = 0;
 29     for(int i=0; i<6; i++)     if(x[i][c]) sum++;
 30     return sum;
 31 }
 32 
 33 void show(int x[][6])
 34 {
 35     for(int i=0; i<6; i++)
 36     {
 37         for(int j=0; j<6; j++) printf("%2d", x[i][j]);
 38         printf("\n");
 39     }
 40     printf("\n");
 41 }
 42 
 43 void f(int x[][6], int r, int c);
 44 
 45 void GoNext(int x[][6],  int r,  int c)
 46 {
 47     if(c<6)
 48         _f(x,r,c+1);   // 填空
 49     else
 50         f(x, r+1, 0);
 51 }
 52 
 53 void f(int x[][6], int r, int c)
 54 {
 55     if(r==6)
 56     {
 57         if(CheckStoneNum(x))
 58         {
 59             N++;
 60             show(x);
 61         }
 62         return;
 63     }
 64 
 65     if(x[r][c]==1)  // 已经放有了棋子
 66     {
 67         GoNext(x,r,c);
 68         return;
 69     }
 70     
 71     int rr = GetRowStoneNum(x,r);
 72     int cc = GetColStoneNum(x,c);
 73 
 74     if(cc>=3)  // 本列已满
 75         GoNext(x,r,c);  
 76     else if(rr>=3)  // 本行已满
 77         f(x, r+1, 0);   
 78     else
 79     {
 80         x[r][c] = 1;
 81         GoNext(x,r,c);
 82         x[r][c] = 0;
 83         
 84         if(!(3-rr >= 6-c || 3-cc >= 6-r))  // 本行或本列严重缺子,则本格不能空着!
 85             GoNext(x,r,c);  
 86     }
 87 }
 88 
 89 int main(int argc, char* argv[])
 90 {
 91     int x[6][6] = {
 92         {1,0,0,0,0,0},
 93         {0,0,1,0,1,0},
 94         {0,0,1,1,0,1},
 95         {0,1,0,0,1,0},
 96         {0,0,0,1,0,0},
 97         {1,0,1,0,0,1}
 98     };
 99 
100     f(x, 0, 0);
101     
102     printf("%d\n", N);
103 
104     return 0;
105 }

 

 
煤球数目
有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),
....
如果一共有100层,共有多少个煤球?
请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
 
 
思路:算出每一层的煤球数量,然后加起来
 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <cstring>
 7 #include <stdio.h>
 8 #define lowbit(x) x&(-x)
 9 
10 using namespace std;
11 const int maxn=1e5+10;
12 typedef long long ll;
13 
14 int main(){
15     ios::sync_with_stdio(0);
16     int c=0,sum=0;
17     for(int i=1;i<=100;i++){
18         c+=i;
19         sum+=c;
20     }
21     cout<<sum<<endl;
22     return 0;
23 }

 

 

凑算式
        B        DEF
A + --- + ------- = 10          (如果显示有问题,可以参见【图1.jpg】)
        C        GHI
 
    
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <cstring>
 7 #include <stdio.h>
 8 #define lowbit(x) x&(-x)
 9 
10 using namespace std;
11 const int maxn=1e5+10;
12 typedef long long ll;
13 int a[9]={1,2,3,4,5,6,7,8,9};
14 int fun(){
15     int A=a[0];
16     int b=a[1];
17     int c=a[2];
18     int def=a[3]*100+a[4]*10+a[5];
19     int ghi=a[6]*100+a[7]*10+a[8];
20     if(A*c*ghi+b*ghi+c*def==10*c*ghi){
21         return 1;
22     }
23     return 0;
24 }
25 int main(){
26     ios::sync_with_stdio(0);
27     int ans=0;
28     
29     while(next_permutation(a,a+9)){
30         ans+=fun();
31     }
32     cout<<ans<<endl;
33     return 0;
34 }

 

 
 
posted @ 2018-04-01 06:48  浅忆~  阅读(135)  评论(0编辑  收藏  举报