可写题应该有 A、B、C、D、F、G、H。其他题感兴趣的同学可以看看。
问题 A: 年龄判断
签到题*1
AC代码:
#include
using namespace std;
int main()
{
int n;
scanf("%d", &n);
if (n <= 3)
printf("infant\n");
else if (n <= 12)
printf("child\n");
else if (n <= 18)
printf("youngster\n");
else if (n <= 25)
printf("youth\n");
return 0;
}
问题 B: 大象喝水
签到题*2,写法很多,可以公式求答案,也可以while循环暴力求解。
AC代码:
#include
using namespace std;
int main()
{
double n, h, r;
scanf("%lf%lf%lf", &n, &h, &r);
double sum = 0;
int ans = 0;
while (sum < n)
{
ans++;
sum += r * r * 3.1415926 * h;
}
printf("%d\n", ans);
return 0;
}
问题 C: 并联电阻
签到题*3
AC代码:
#include
using namespace std;
int main()
{
double n, m;
scanf("%lf%lf", &n, &m);
printf("%.2f\n", 1 / (1 / n + 1 / m));
return 0;
}
问题 D: 学长自救计划
题面有锅,输入的是n、m、pos而不是m、n、pos。
走廊有两头,那么我们考虑走两边逃跑哪边需要的体力更少即可。
顺便先提一下三目运算 ?:
a?b:c,其中a是一个表达式,b和c是一个语句。
等价于
if(a)
b;
else
c;
AC代码:
#include
using namespace std;
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, m, pos;
scanf("%d%d%d", &n, &m, &pos);
int ans_left = 0, ans_right = 0;
for (int i = 1; i <= n; i++)
{
int a, b;
scanf("%d %d", &a, &b);
if (a <= pos) //怪物在左边
ans_left += b;
if (a >= pos) //怪物在右边
ans_right += b;
}
printf("%d\n", ans_left < ans_right ? ans_left : ans_right);
}
return 0;
}
问题 E: 花海
这题为了代码美观,思路清晰,用到了函数判断素数。感兴趣的同学可以先了解一下函数。本周会讲解。
AC代码:
#include
using namespace std;
bool ispreme(int x) //函数判断素数
{
int i;
for (i = 2; i * i <= x; i++)
{
if (x % i == 0)
return false;
}
return true;
}
int main()
{
int n;
scanf("%d", &n);
int i, j, ans = 0;
for (i = 2; i <= n; i++)
{
for (j = 2; j * i <= n; j++)
{
if (ispreme(i) && ispreme(j))
ans++;
}
}
printf("%d\n", ans);
return 0;
}
问题 F: 今夕何夕
将节日分别记作1、2、3、4。然后用二维数组a[i][j]记录 第i个人在第j个节日是否有空。
AC代码:
#include
using namespace std;
char s[10];
int a[10][10];
int main()
{
for (int i = 1; i <= 6; i++)
{
int n;
scanf("%d", &n);
for (int j = 1; j <= n; j++)
{
scanf("%s", s);
if (s[0] == 'N' && s[1] == 'Y')
a[i][1] = 1;
if (s[0] == 'I' && s[1] == 'L')
a[i][2] = 1;
if (s[0] == 'T' && s[1] == 'D')
a[i][3] = 1;
if (s[0] == 'N' && s[1] == 'D')
a[i][4] = 1;
}
}
int ans = 0;
for (int i = 1; i <= 4; i++)
{
int sum = 0;
for (int j = 1; j <= 6; j++)
sum += a[j][i];
if (sum == 6) //6个人都有空
{
ans = i;
break;
}
}
if (ans == 0)
printf("What a shame!\n");
else if (ans == 1)
printf("New Year\n");
else if (ans == 2)
printf("International Labor Day\n");
else if (ans == 3)
printf("The Dragon Boat Festival\n");
else if (ans == 4)
printf("National Day\n");
return 0;
}
问题 G: 一个餐厅
本题用到的abs(x)是math.h
头文件中的一个函数,返回x的绝对值。
AC代码:
#include
using namespace std;
int a[310];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
int ans1, ans2 = 100000000000;
for (int i = n; i >= 1; i--)
{
int sum = 0;
for (int j = 1; j <= n; j++)
{
if (i != j)
{
sum += abs(a[j] - a[i]);
}
}
if (sum < ans2) //先保证距离最近
{
ans1 = a[i];
ans2 = sum;
}
else if (sum == ans2) //再保证坐标最小
{
if (a[i] < ans1)
{
ans1 = a[i];
}
}
}
printf("%d %d\n", ans1, ans2);
return 0;
}
问题 H: acm可好玩了
这题应该可以写,需要注意的是,你的所有输出最终都在一个文件中,测评系统评判你的题目是否正确,就是对应预先就有的标准答案文件和你的输出文件是否一样,因此我们最后一次性输出,和每次输出,最后的效果一致。
AC代码:
#include
using namespace std;
char s[110];
int main()
{
while (~scanf("%s", s))
{
int len = strlen(s);
for (int i = len - 1; i >= 0; i--)
printf("%c", s[i]);
printf(" ");
}
return 0;
}
问题 I: 小H的面试难题
比较裸的对顶堆动态维护中位数。nlogn可写。
对顶堆详解博客
AC代码:
#include
using namespace std;
priority_queue<int> q1;
priority_queue<int, vector<int>, greater<int>> q2;
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
int temp;
scanf("%d", &temp);
q2.push(temp);
if (i & 1) //奇数
{
while (q1.size() != q2.size() + 1)
{
int res = q2.top();
q2.pop();
q1.push(res);
}
while (q1.top() > q2.top())
{
int res1 = q1.top();
int res2 = q2.top();
q1.pop(), q2.pop();
q2.push(res1);
q1.push(res2);
}
printf("%d\n", q1.top());
}
}
return 0;
}
问题 J: 最大的差
此题卡时间。
常规解法就是枚举一个ai,再从后面找所有aj,更新答案。
这样时间复杂度是 O ( n 2 ) O(n^2) O(n2),数据范围 100000 100000 100000,会TLE。我们可以预处理一个后缀最小值。这样可以把时间复杂度降到 O ( n ) O(n) O(n)
AC代码:
#include
using namespace std;
int a[100010];
int pre[100010]; //pre[i]表示区间[i,n]的最小值
int main()
{
int n;
scanf("%d", &n);
pre[n + 1] = 2000000001;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
for (int i = n; i >= 1; i--)
{
pre[i] = pre[i + 1] < a[i] ? pre[i + 1] : a[i];
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
ans = ans > a[i] - pre[i] ? ans : a[i] - pre[i];
}
printf("%d\n", ans);
return 0;
}