第一次排位赛题解及总结(一)
D题
倩倩学姐,一个大三的老阿姨呢,但是呢她还有一颗坚持竞赛的心。所以他碰到一个奥林匹克竞赛的数学问题,她搞不定很难受,决定暴饮暴食。聪明而优秀的学霸熊熊学长看到这一幕决定帮他解决这个问题。这个问题是:
我们描述 K:
k! = 1 * 2 * …* (k - 1) *k
我们表示 S:
S = 1 * 1! + 2 * 2! + … +
(n - 1) * (n-1)!
然后 S 对 n 去模是 ___________
你将得到一个整数n.
你需要计算 S 对 n 取模的值
输入
第一行输入一个整数 T(T < 1000), 表示测试用例的行数.
对于每个测试用例,都有一行包含一个整数 n.
保证 2
输出
对于每个测试用例,打印一个整数 S 对 n 取模后的值.
提示
第一个测试用例 S = 1* 1!= 1, 并且 1 的模 2 运算 1.
第二个测试用例 S = 11!+2 2!= 5 , 并且 5 对 3 取模是 2.
Sample Input |
---|
2 |
2 |
3 |
Sample Output |
---|
1 |
2 |
#include <stdio.h>
int main()
{
int b;
long long int a;//由于是累乘,数比较大,一定要注意类型;
scanf("%d",&b);
while(b--)
{
scanf("%lld",&a);
printf("%lld\n",a-1);
}
return 0;
}
这个题特别容易被唬住,初次大概看了一遍题目,以为很复杂,没想到,只要跟着题目理解,再结合一下所给出的样例,你就会很神奇的发现只需要减一,感觉被整个世界欺骗了。
F题
熊熊学长一天在实验室里闲的没事。他想做点游戏打发一下时间。他就拉上了和他同样无聊的柴柴学长。
两位学长要玩的游戏是什么呢?很简单,它是这样定义的:
1、 本游戏是一个二人游戏;
2、 有一堆石子一共有n个;
3、 两人轮流进行;
4、 每走一步可以取走1…m个石子;
5、 最先取光石子的一方为胜;
如果游戏的双方使用的都是最优策略,请输出哪个人能赢。
Input
输入数据首先包含一个正整数C(C<=100),表示有C组测试数据。
每组测试数据占一行,包含两个整数n和m(1<=n,m<=1000),n和m的含义见题目描述。
Output
如果先走的人能赢,请输出“first”,否则请输出“second”,每个实例的输出占一行。
Sample Input |
---|
2 |
23 |
4 |
Sample Output |
---|
first |
second |
#include<stdio.h>
int main()
{
int t,m,n,i;
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d %d",&n,&t);
if(n%(t+1)!=0)
printf("first\n");
else
printf("second\n");
}
return 0;
}
这道题是其实是一道巴什博弈------两个顶尖聪明的人在玩游戏,有n个石子,每次最少取一个,最多取t个,直到最后一个人不能拿为止。感觉像是一门玄学,哈,其实不是。
假设,现在有t+1个石子,无论先手如何取,后手都能一次性取完,即后手必胜,以此类推,只要满足n=k*(t+1),无论先手取几个,只要后手保证剩下的为(t+1)的整数倍,后手必胜。同理,只要先手拿走之后保证剩下的石子是(t+1)的整数倍,无论后手如何取,先手必胜。
所以只要判断n%(t+1)是否为零即可。
G题
有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
Input
输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。
Output
对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。
Sample Input
1 | ||||
5 | ||||
7 | ||||
3 | 8 | |||
8 | 1 | 0 | ||
2 | 7 | 4 | 4 | |
4 | 5 | 2 | 6 | 5 |
Sample Output |
---|
30 |
#include<stdio.h>
#define max(a,b) ((a)>(b)?(a):(b));
int n,i,j;
int b[100][100];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<=i;j++)
{
scanf("%d",&b[i][j]);
}
}
for(i=n-2;i>=0;i--)//由于从上往下只能保证局部最优,所以从下往上找,找出每行的最大,寻找最佳途径;
for(j=0;j<=i;j++)
{
b[i][j]+=max(b[i+1][j],b[i+1][j+1]);
}
printf("%d\n",b[0][0]);
}
return 0;
}
第一次写题解,时间比较仓促,有些地方,考虑不周,而且题目没有补充完,另一部分尽早补上,如果哪些地方存在问题,还望不吝赐教。