ACM 暑期训练第一天习题 简单排序 + 思维题 + 位运算
最后两个题为思维题
问题 A: 成绩评级
题目描述
现在我们有一套独特的评级规则:
如果你的分数 X 满足 X = 4*n+1,即除以 4 余 1,那么你的分数为 A 等。
同样的如果你的分数满足 X = 4*n+3,那么你的分数为 B 等。
如果你的分数满足 X = 4*n+2,那么你的分数为 C 等。
如果你的分数是其他情况,那么为 D 等。
现在给出你的分数,你有一次修改自己分数的机会,当然不能太过分,所以这个修改被限制为:增加 0 或 1 或 2。
请考虑最佳情况给出自己能拿到的最佳评级。
输入
输入为一个整数 X,即你的分数。
输出
输出你能拿到的最高评级。
样例输入
33
样例输出
A
//因为他的取余只有0,1,2,3这四种情况,然而他可以改变一次成绩取最佳成绩,所以最终可以取A,B
#include<stdio.h>
#include<stdlib.h>
int main() {
int s;
scanf("%d", &s);
if (s % 4 == 2)
printf("B");
else
printf("A");
return 0;
}
问题 B: 排序
时间限制: 1 Sec 内存限制: 32 MB
题目描述
输入n个整数,请输出他们按非递减排序后的结果。
输入
输入的第一行为一个正整数n(1 ≤ n ≤ 1000),代表有n个整数。
接下来第2到第n + 1行包含n个数字,表示待排序的n个数字。
输出
输出一行,包括n个数字,每两个数字之间有一个空格。
样例输入
4
2
1
-2
3
样例输出
-2 1 2 3
//此排序为快速排序
#include<stdio.h>
#include<stdlib.h>
int a[1000];
int partition(int low, int high) {
int pivotkey = a[low];
while (low < high) {
while (low < high&&a[high] >= pivotkey)--high;
a[low] = a[high];
while (low < high&&a[low] <= pivotkey)++low;
a[high] = a[low];
}
a[low] = pivotkey;
return low;
}
void soft(int low, int high) {
int pivotloc;
if (low < high) {
pivotloc = partition(low, high);
soft(low, pivotloc - 1);
soft(pivotloc + 1, high);
}
}
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i <n; i++)
scanf("%d", &a[i]);
soft(0, n-1);
for (int i = 0; i <n; i++){
if(i)
printf(" ");
printf("%d", a[i]);
}
return 0;
}
问题 C: 计算n!
时间限制: 1 Sec 内存限制: 128 MB
[提交][状态][讨论版][命题人:201706060614]
题目描述
给定一个正整数n,请输出n!。(1 ≤ n ≤ 10)
n!=1×2×3×…×n。
输入
包含一个整数n。
输出
输出n!的值。
样例输入
3
样例输出
6
#include<stdio.h>
#include<stdlib.h>
int sum(int n) {
int sum = 1;
for (int i = 1; i <= n; i++)
sum *= i;
return sum;
}
int main() {
int n;
scanf("%d", &n);
printf("%d", sum(n));
return 0;
}
问题 D: 奇数的个数
时间限制: 1 Sec 内存限制: 128 MB
题目描述
输入n个正整数,输出其中奇数的个数。
输入
第一行包括一个正整数n(1 ≤ n ≤ 5000000)。
第二行包括n个正整数,两个整数之间由空格分开。
保证每个正整数小于100000。
输出
输出包含一个整数,表示n个数中奇数的个数。
样例输入
3
1 3 4
样例输出
2
提示
要求使用位运算解决此题。
#include<stdio.h>
int main() {
int a,n, flag = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a);
if (a&1) //与运算 判断奇偶
flag++;
}
printf("%d", flag);
}
问题 E: longlong下最大的有效斐波那契数
题目描述
请输出longlong情况下最大的有效斐波那契数
输入
该题无输入
输出
请输出longlong情况下最大的有效斐波那契数
样例输入
无
样例输出
无
#include<stdio.h>
#include <stdlib.h>
int main(void)
{
long long int pre = 0;
long long int cur = 1;
long long int next = 0;
long long int cnt = 1;
while (1)
{
next = cur + pre;
pre = cur;
cur = next;
if (cur + pre < cur)
break;
}
printf("%lld", cur);
system("pause");
return 0;
}
问题 F: 今天全场的消费,苏公子买单
题目描述
众所周知,苏公子是陕科大品学兼优的好学生,平时喜欢帮助同学,看见同学有需要就控制不住自己。这不,今天,苏公子看见同学们的算法水平堪忧,想买一些算法书送给同学们。虽然今天在书店全场的消费由苏公子买单,但是苏公子带的现金有限,他又想要尽量多买一些算法书送给同学。遗憾的是,苏公子今天出门忘记了带脑子,聪明的你能帮帮他吗。要是你帮助苏公子解决了这个问题,他就会送你一本算法导论。
输入
有多组测试数据。
输入第一行有两个整数N,M。 N代表苏公子想要买的算法书数量, M代表苏公子带的现金金额。1 < N < 100,1 < M < 10000。
输入第二行,有N个数,分别代表每一本算法书的价格。
输出
输出一个数,代表苏公子最多能买多少本算法书。
样例输入
3 100
1 2 3
3 5
1 2 3
样例输出
3
2
#include<stdio.h>
#include<stdlib.h>
void soft(int a[100],int n) {
for(int i=0;i<n-1;i++)
for(int j=0;j<n-1-i;j++)
if(a[j]>a[j+1]){
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
int main() {
int n, m;
while(scanf("%d %d", &n,&m)!=EOF){
int a[100],sum=0,flag=0;
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
soft(a,n);
for(int i=0;i<n;i++){
sum+=a[i];
if(sum<m) {
flag++;
}
}
printf("%d\n",flag);
}
}
问题 G: 小小粉刷匠
题目描述
在山的那边有一群快乐的小粉刷匠, 他们喜欢粉刷一切物品。
某天村长从山的另一头拿来了一块木板,希望寻找村里粉刷技术最高超的粉刷匠来刷它。
海廷和明昊是村里粉刷技术最高超的粉刷匠,村长打算让他们来进行粉刷,这时候他们对粉刷方案出现了分歧,最后决定从所用能用的粉刷方案中重新进行选择,你路过的时候他们希望你能帮忙计算总共有多少种粉刷方案。
木板为一块纯白色木板,上面分布着2*n(2<= n <= 20)个格子,但是作为粉刷匠的习惯左上角和右下角的格子一定要涂黑,粉刷匠只能使用黑色颜料去选择粉刷剩余白色格子,每一列至少要粉刷一格, 现在需要你计算总共有多少种粉刷方案。
粉刷方案可能会过大, 所以对最后的总数求模 1000000009
当n = 2时, 木板如上图, 粉刷方案一共4种
输入
本题有多组测试样例
每一组样例第一行输入一个n (2 <= n <= 200)
输出
输出涂色方案总数,总数求模1000000009
样例输入
2
3
21
样例输出
4
12
649045832
提示
左上角第一格和右下角最后一格已经被粉刷了,当N = 2时, 粉刷方案共四种:
就是最左边一列和最右边一列的组合有4种情况
中间每一列有3种情况
中间有n-2列
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
const int mod=1000000009;
int main() {
int n;
while(scanf("%d",&n)!=EOF){
long long int ans=1;
for(int i=0;i<n-2;i++){
ans=(ans%mod*3%mod)%mod;
}
printf("%lld\n",(ans*4)%mod);
}
return 0;
}
问题 H: 居居倩的疑惑
题目描述
居居倩来到了一个n*m的黑白格地板上,她想不重复地走完所有白格,但她不知道最少要多久才能走完,你能帮帮她么?
有以下两种走法
1.从白格隔一个黑格直线跳到下一个白格,耗时3分钟
2.从白格走到斜上或斜下方的白格,耗时4分钟
已知黑白格地板的左上角为白格,居居倩也将在左上角开始她的游戏
下图是5 * 6的黑白格地板
输入
两个数 N 和 M (1 ≤ N,M ≤ 100)
输出
居居倩走完白格的分钟数
样例输入
5 6
样例输出
43
#include<stdio.h>
#include<stdlib.h>
int main() {
int n, m, flag;
scanf("%d %d", &n, &m);
if (n & 1) { //n为奇
flag = 0;
for (int i = 1; i <= m; i++) {
if (i & 1) {
flag += n / 2 + 1;
}
else {
flag += n / 2;
}
}
}
else { //n为偶
flag = 0;
for (int i = 1; i <= m; i++) {
flag += n / 2;
}
}
//printf("flag:%d\n", flag);
if ((n == 1) && (m == 1))
printf("%d", 0);
else if ((m == 1) && (n>1))
printf("%d", (flag - 1) * 3);
else if ((n == 1) && (m>1))
printf("%d", (flag - 1) * 3);
else if ((flag >= 2) && (m >= 2) && (n >= 2))
printf("%d", (flag - 2) * 3 + 1 * 4);
return 0;
}