比赛信息
题目难度
题目详解
解析:首先判断数组中每个数是否满足不超过h的条件,接着对这个数组排序过后,判断每两个数之间的差值是否相等即可得到答案。
代码如下:
1、C++——vertor数组以及sort函数
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
long long h;
cin >> n >> h;
vector<long long> nums(n);
for (int i = 0; i < n; ++i) {
cin >> nums[i];
}
if (n == 1) {
cout << "我要易大山啦!" << endl;
return 0;
}
sort(nums.begin(), nums.end());
if (n == 2) {
if (abs(nums[1] - nums[0]) <= h) {
cout << "我要易大山啦!" << endl;
}
else {
cout << "像一直在被优化,没队要的是我" << endl;
}
return 0;
}
for (int i = 2; i < n; ++i) {
if (nums[i] - nums[i - 1] != nums[1] - nums[0] || abs(nums[i] - nums[i - 1]) > h) {
cout << "像一直在被优化,没队要的是我" << endl;
return 0;
}
}
cout << "我要易大山啦!" << endl;
return 0;
}
2、C语言——冒泡排序
#include<stdio.h>
int n;
long long a[1010], h;
int main() {
scanf("%d%lld", &n, &h);
int flag = 0;
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
if (a[i] > h) flag = 1; // 判断是否小于 h
}
for (int i = 1; i <= n; i++) { // 冒泡排序
for (int j = i + 1; j <= n; j++) {
if (a[i] > a[j]) {
long long x = a[i];
a[i] = a[j];
a[j] = x;
}
}
}
long long num = a[2] - a[1];
for (int i = 3; i <= n; i++) { // 判断每两个数之间的差值是否相等
if (a[i] - a[i - 1] != a[i - 1] - a[i - 2])
{
flag = 1;
break;
}
}
if (flag) printf("像一直在被优化,没队要的是我\n");
else printf("我要易大山啦!\n");
}
解析:题目所给的卡牌名为整数1~100,所以定义一个大小为
代码如下:
#include <stdio.h>
#include <string.h>
const int INF = 1e9;
int s1[101] = { 0 };
int s2[101];
signed main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
int x, y;
scanf("%d%d", &x, &y);
s1[x] = y; // 记录每种卡牌需要的数量
}
for (int i = 1; i <= 100; i++)
s2[i] = INF; // 将每种卡牌的初始单价设为极大值
while (m--)
{
int ka;
scanf("%d", &ka);
for (int i = 1; i <= ka; i++)
{
int x, y;
scanf("%d%d", &x, &y);
if (y < s2[x])
s2[x] = y; // 更新每种卡牌的最低价格
}
}
int ans = 0;
for (int i = 1; i <= 100; i++) // 计算价钱
{
if (s1[i] == 0) // 为 0 说明不需要买该卡牌,跳过
continue;
ans += s1[i] * s2[i];
}
printf("%d", ans); // 输出答案,完美结束
}
解析:这一题的主要思路是——先把所需要的卡牌和卡牌店里有的卡牌都记录下来。然后依次枚举每种卡牌,寻找该卡牌在各个卡牌店里的价钱和数量,再计算是否可以买齐该卡牌以及买齐所需的价钱,最后再汇总所有卡牌的价钱得到答案。具体详见代码注释。该题的
代码如下:
#include <stdio.h>
#include <string.h>
struct nate
{
char id[20];
int a, b;
} s[101][101];
typedef struct nate1
{
int a, b;//储存卡牌店里的牌的编号-id,价格-a,数量-b
} sta; //用来储存某一种卡牌的价格和数量
int main()
{
int n, m;
scanf("%d%d", &n, &m);
char s1[201][20]; // 需要购买的卡牌编号
int s2[201];
int s3[201];
for (int i = 1; i <= n; i++)
scanf("%s %d", &s1[i], &s2[i]);
for (int i = 1; i <= m; i++)
{
int kx;
scanf("%d", &kx);
s3[i] = kx;
for (int j = 1; j <= kx; j++)
{
char id[20];
int a, b;
scanf("%s %d%d", &id, &a, &b);
if (b > 3)//因为一家店同一种卡牌最多买 3 张,所以大于 3 的都按 3 计 算
b = 3;
strcat(s[i][j].id, id);
s[i][j].a = a;
s[i][j].b = b;
}
}
int ans = 0;
for (int i = 1; i <= n; i++) { //依次计算购买每一种卡牌的价钱
char id[20] = {};
strcat(id, s1[i]);
sta sc[101];
int kn = 0, kans = 0;// kn-当前有几家店有当前需要的卡牌,kans - 当前需要的卡牌总数
for (int j = 1; j <= m; j++) { //通过枚举把所有店里的当前需要的卡牌找出来
for (int k = 1; k <= s3[j]; k++) {
if (strcmp(s[j][k].id, id) == 0) {
kn++;
sc[kn].a = s[j][k].a;
sc[kn].b = s[j][k].b;
kans += s[j][k].b;
}
}
}
if (kans < s2[i])//总数小于需要购买的数量,肯定买不齐
{
printf("bu yong bao jin bi la !");
return;
}
for (int j = 1; j < kn; j++) {//排序,按照价钱从小到大
for (int k = 1; k <= kn - j; k++) {
if (sc[k].a > sc[k + 1].a)
{
sta ta = sc[k];
sc[k] = sc[k + 1];
sc[k + 1] = ta;
}
}
}
int kx = s2[i];
for (int j = 1; j <= kn; j++)//计算价钱
{
if (kx > sc[j].b)
{
kx -= sc[j].b;
ans += sc[j].a * sc[j].b;
}
else
{
ans += sc[j].a * kx;
break;
}
}
}
printf("%d", ans);//输出答案, 完美结束
return 0;
}
解析:最基础的,你只要会CV即可,printf函数
代码如下:
#include<stdio.h>
int main() {
printf("不翘课也能打 ACM!\n");
return 0;
}
现在OJ官网已经修改了题面:最后的要求由“这个数至少可以由几个
题目看起来很复杂,其实照着结论判断给定的数是奇数还是偶数即可,偶数的话就输出 2,奇数的话就输出 3。要注意的是:题面中要求的是可以由几个
代码如下:
#include<stdio.h>
int main() {
int n;
scanf("%d", &n);
if (n % 2 == 0) printf("2\n");
else printf("3\n");
return 0;
}
如果按照原题目来解决的话,我们只需要加一步判断:判断
代码如下:
#include<stdio.h>
bool is_prime(int n)
{
if(n==1)
return 0;
for(int i=2;i<=n/i;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main() {
int n;
scanf("%d", &n);
if (n % 2 == 0)
printf("2\n");
else {
if (is_prime(n - 2))
printf("2\n");
else
printf("3\n");
}
return 0;
}
解析:这种题目属于构造题,需要分情况讨论:
当 n=1 时,只要求 k>=1 即可满足条件;当 n>=2 时,我们可以发现,最优策略是一大一小的排列,这样可以让每两个相邻的数字相加的和的最大值尽可能最小,类似于 n=6 时,输出 6 1 5 2 4 3,此时只要保证k>=n+1 即可,当然也可以最大数字在最右边 3 4 2 5 1 6,这样也满足条件。
代码如下:
#include<stdio.h>
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, k;
scanf("%d%d", &n, &k);
if (n == 1)
{
if (k >= 1)
printf("1 ");
else
printf("-1");
printf("\n");
continue;
}
if (k < n + 1)
printf("-1\n");
else
{
int x = 1, y = n;
for (int i = 1; i <= n; i++)
{
if (i % 2)
printf("%d ", y--);
else
printf("%d ", x++);
}
printf("\n");
}
}
return 0;
}
解析:使用
代码如下:
#include<stdio.h>
void solve() {
int n;
scanf("%d", &n);
int odd = 0, even = 0;
for (int i = 1; i <= n; i++) {
int x; scanf("%d", &x);
if (x % 2 == 1) odd += x; //hjl 拿的小水怪数量
else even += x;//lyh 拿的小水怪数量
}
if (even > odd) printf("YES\n");
else printf("NO\n");
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
解析:简单模拟题,按照题意模拟即可。只需要注意几个限制条件,血量不能大于 10,血量小于 0 直接结束。
代码如下:
#include <stdio.h>
#include <string.h>
int n, jy, lv;
int a, x, hp = 10;
void LV()
{
int o = 1;
while (jy >= o) // 经验值大于上限
{
jy -= o;
lv++; // 等级加 1
o *= 2; // 经验上限乘 2
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &x, &a);
hp -= x; // 血量减少
if (hp <= 0) // 血量为 0,结束
break;
jy += a; // 先把经验累加, 最后计算等级
if (hp > 10) // 血量超过上限
hp = 10;
}
LV(); // 计算等级
printf("%d %d", lv, jy); // 输出答案,完美结束
return 0;
}
解析:较为简单的博弈问题,可以发现不管对方拿多少石子,我们可以控制一轮过后总是拿走三颗石子。因此若初始石子对3取模有余数的话,可以保证最后一次一定是 Alice 拿石子,反之则是每轮二人操作后都会拿走 3 颗,Bob 会拿走最后一颗石子。
代码如下:
#include<stdio.h>
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n;
scanf("%d", &n);
if (n % 3 == 0)
printf("Bob\n");
else
printf("Alice\n");
}
}
暂无评论内容