A 我爱编程,编程使我快乐。
签到,直接输出就行
#include <stdio.h>
int main()
{
printf("我爱编程,编程使我快乐。");
}
B 二进制翻转
根据题意只需要计算数组中连续的0的段数即是答案,注意到每个连续的0的段前面必定有一个1(如果起始为0单独计算),所以记录前1后0的位置的数量即是连续的0的段的数量。
#include <stdio.h>
int n;
int a[200005];
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
int ans = 0;
if (a[0] == 0) ans++;
for (int i = 1; i < n; i++) {
if (a[i] == 0 && a[i - 1] == 1) ans++;
}
printf("%d\n", ans);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n;
int a[200005];
int main() {
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
int ans = 0;
if (a[0] == 0) ans++;
for (int i = 1; i < n; i++) {
if (a[i] == 0 && a[i - 1] == 1) ans++;
}
cout << ans << endl;
return 0;
}
C 二进制扩列
由题意知原先的字符串经过扩展后必定是一边一个0另一边一个1,所以使用两个变量标记左右边界,如果符和一边是0另一边是1则符和条件,可以继续收缩。由于你要得到最短的最初的字符串,所以你只要找到不符合的位置,然后输出此时字符串的长度即可。
#include <stdio.h>
char s[100005];
int main() {
int n;
scanf("%d%s", &n, s);
int l = 0, r = n - 1, ans = 0;
while (s[l] != s[r] && l < r) {
l++, r--, ans++;
}
printf("%d\n", n - ans * 2);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
string s;
cin >> n >> s;
int l = 0, r = n - 1, ans = 0;
while (s[l] != s[r] && l < r) {l ++, r --, ans ++;}
cout << n - ans * 2 << endl;
return 0;
}
D 睡过去的jxh仍在学习
对数组a进行排序,然后把前m个小的数相加即可,注意题目的数据范围,不能用n^2的排序方法,可以用快排、归并之类的,使用c++的话,可以直接用sort函数。如果不会这些的话,注意到数组a中的元素都是1e5以内的正整数,可以开一个数组b来记录数组a中元素出现的个数,即b[x]代表x在a中出现的次数,x为0时,没有出现过。这样就可以从1开始遍历b,找到a中前m个小的数,把它们相加即可。
#include <stdio.h>
int a[100005];
int main() {
int n, m, cnt = 0;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
int x;
scanf("%d", &x);
a[x]++;
}
long long ans = 0;
for (int i = 1; i <= 100000; i++) {
long long x = a[i];
if (x > m - cnt) x = m - cnt;
cnt += x;
ans += i * x;
if (cnt == m) break;
}
printf("%lld", ans);
return 0;
}
E 寝室的宝箱(简单版)
简单的加减计算,对于输入的数字和字符调用相关的式子即可
#include<stdio.h>
int main()
{
int x,y;
char ch;
scanf("%d %c %d",&x,&ch,&y);
printf("%d",(ch=='+'?x+y:x-y));
return 0;
}
F 寝室的宝箱(困难版)
如果选择整形进行计算需要考虑使用longlong,对于除法需要特判一下,另外使用浮点数进行计算由于没有卡精度所以也是可以过的。
#include<stdio.h>
int main()
{
long long x,y;
char ch;
scanf("%lld %c %lld",&x,&ch,&y);
if(ch=='/')
{
if(x%y)printf("%.2lf",(double)x/y);
else printf("%lld",x/y);
}
else printf("%lld",ch=='+'?x+y:(ch=='-'?x-y:x*y));
return 0;
}
G 排队
单向链表的简单模拟,反向记录一下每个人后面的人即可,可以标记一下前面有人的人的编号没有标记的就是队首,另外有n可能为1赛时很多人wa这个点了。
#include<stdio.h>
int a[5005],st[5005];
int main()
{
int n,h;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[y]=x;
st[x]=1;
}
for(int i=1;i<=n;i++)
if(!st[i])
{
h=i;
break;
}
while(h)
{
printf("%d ",h);
h=a[h];
}
return 0;
}
H jxh和lhy的决斗
大模拟,模拟过程见注释
#include <stdio.h>
struct player
{
int hp, mp, atk, x, y, z;
int hpx, def, deft;//分别是血量最大值、目前护盾值、护盾持续时间
}jxh, lhy;
//攻击函数
struct player atk(struct player a, struct player b)
{
int x = a.atk;
//先判断护盾值是不是能够抵挡此次攻击,如果可以,只扣除护盾
if (b.def >= x) b.def -= x;
//护盾值小于伤害的话,血量扣除使用护盾抵扣后的伤害并将护盾值置为0
else
{
x -= b.def;
b.def = 0;
b.hp -= x;
}
return b;
}
//回血函数
struct player rec(struct player a)
{
a.hp = a.hp + a.x;
//需要注意回血不能超过血量上限
if (a.hp > a.hpx) a.hp = a.hpx;
return a;
}
//防御函数
struct player def(struct player a)
{
//重置护盾值和护盾持续时间
a.def = a.y;
a.deft = 3;
return a;
}
//释放技能函数
struct player mfa(struct player a, struct player b)
{
//判断mp是否足够释放技能,可以的话使用攻击函数攻击三次
if (a.mp >= a.z)
{
b = atk(a, b);
b = atk(a, b);
b = atk(a, b);
}
return b;
}
h
模拟就行,具体看代码里的注释
int main()
{
int t;
scanf("%d", &t);
while (t -- )
{
scanf("%d%d%d%d%d%d", &jxh.hp, &jxh.mp, &jxh.atk, &jxh.x, &jxh.y, &jxh.z);
scanf("%d%d%d%d%d%d", &lhy.hp, &lhy.mp, &lhy.atk, &lhy.x, &lhy.y, &lhy.z);
//记录血量上限
jxh.hpx = jxh.hp;
lhy.hpx = lhy.hp;
//重置护盾值和护盾持续时间
jxh.def = jxh.deft = lhy.def = lhy.deft = 0;
int n, flag = 0, ans = 0;
//判断谁先手,并记录是否交换
if (jxh.atk < lhy.atk)
{
struct player temp = jxh;
jxh = lhy;
lhy = temp;
flag = 1;
}
scanf("%d", &n);
//经过判断后变量jxh先手,变量lhy后手
while (n -- )
{
int a, b;
scanf("%d%d", &a, &b);
//如果已经出现结果,跳过
if (ans) continue;
//护盾持续时间减1,如果持续时间为0,护盾值归零
jxh.deft = jxh.deft - 1;
if (jxh.deft < 0) jxh.deft = 0;
if (!jxh.deft) jxh.def = 0;
//判断操作
switch (a)
{
case 1:
lhy = atk(jxh, lhy);
break;
case 2:
jxh = rec(jxh);
break;
case 3:
jxh = def(jxh);
break;
case 4:
lhy = mfa(jxh, lhy);
//注意释放技能后要扣除mp
if (jxh.mp >= jxh.z) jxh.mp -= jxh.z;
break;
}
//判断是否出现结果
if (lhy.hp <= 0)
{
ans = 1;
continue;
}
lhy.deft = lhy.deft - 1;
if (lhy.deft < 0) lhy.deft = 0;
if (!lhy.deft) lhy.def = 0;
switch (b)
{
case 1:
jxh = atk(lhy, jxh);
break;
case 2:
lhy = rec(lhy);
break;
case 3:
lhy = def(lhy);
break;
case 4:
jxh = mfa(lhy, jxh);
if (lhy.mp >= lhy.z) lhy.mp -= lhy.z;
break;
}
if (jxh.hp <= 0) ans = -1;
}
//平局
if (!ans) printf("-_-\n");
else
{
//若ans为1,先手赢,否则后手赢
//flag为1时lhy为先手,否则jxh为先手
if (flag) printf("%s\n", ans == 1 ? "lhy!lhy!lhy!!!" : "不愧是你啊,jxh!");
else printf("%s\n", ans == -1 ? "lhy!lhy!lhy!!!" : "不愧是你啊,jxh!");
}
}
}