文章目录
装备二选一(一)
66E61d 沉迷 RPG 游戏,且喜欢与人比赛打木桩(双方分别对两个完全相同且无限血量的目标进行普通攻击,规定时间内输出高的一方获胜)。这天 66E61d 击败了一只 boss 后发现该 boss 掉落了一件武器,66E61d 想知道这件武器是否能替换掉他手中的武器,使他当天晚上可以在打木桩比赛中获得更高的输出能力。
已知 66E61d 的普通攻击有 0 % 0\% 0% 的概率产生暴击,我们称这个概率为暴击率,普通攻击伤害不为 0 0 0 。
* 手中的武器会为他增加
a
%
a\%
a% 的暴击率,发生暴击时会使他本次普通攻击伤害变为原来的
b
b
b 倍。
* boss 掉落的武器会为他增加
c
%
c\%
c% 的暴击率,发生暴击时会使他本次普通攻击伤害变为原来的
d
d
d 倍。
输入描述
输入一行四个整数 输入一行四个整数
a
,
b
,
c
,
d
(
0
≤
a
,
c
≤
100
,
1
≤
b
,
d
≤
10
)
a,\ b,\ c,\ d\ \ (0\leq a,\ c\leq 100,\ 1\leq b,\ d\leq10)
a, b, c, d (0≤a, c≤100, 1≤b, d≤10)
输出描述
若 boss 掉落的装备可以使 66E61d 获得更高的输出能力,输出 `YES` ,否则输出 `NO` 。
解题思路
比较攻击力的增量
AC代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define int long long
#define fi first
#define se second
#define PII pair<int,int>
#define ALL(x) x.begin(),x.end()
const int N=2e5+10;
void solve()
{
int a,b,c,d;cin>>a>>b>>c>>d;
if(c*(d-1)>a*(b-1)) cout<<"YES";
else cout<<"NO";
}
signed main()
{
IOS
int t;
// cin>>t;
t=1;
while(t--)solve();
return 0;
}
百变吗喽
”你说得对,但是《黑神话:悟空》为中国大陆游戏公司游戏科学开发的一款动作角色扮演游戏,采用虚幻5引擎制作,以小说《西游记》为背景设定,玩家将扮演一位“天命人”,为了探寻昔日传说的真相,踏上一条充满危险与惊奇的西游之路。游戏于2020年8月20日公布首段实机演示,在2023年12月8日官方发布的发售日短片中宣布游戏发售日期为2024年8月20日。”
你虽然不是大圣也不是天命人,去不了西天取不了经,但你作为百变吗喽能够帮助小豫同学完成暑假作业,你可以变成任意一个小写字母,然后插入到小豫同学所写的单词中,来使得小豫同学最终的单词和正确答案一模一样。
现在给你小豫同学所写的单词
s
s
s,和标准答案
t
t
t (均为只由小写字母组成的字符串,且一定有
l
e
n
(
s
)
=
l
e
n
(
t
)
−
1
len(s) = len(t)-1
len(s)=len(t)−1 ),你变为任意一个字母插入到任意位置(某个字母的后面或者整个单词的最前面)。 问有多少种插入的方案能够使得插入字母后
s
s
s 和
t
t
t 相同,并给出每种方案的插入位置和变化的字母。
输入描述
第一行输入一个字符串
s
s
s
第二行输入一个字符串
t
t
t
保证
(
1
≤
l
e
n
(
s
)
<
1
0
6
)
( 1\le len(s) < 10^6 )
(1≤len(s)<106)
输出描述
第一行输出方案数
n
n
n,
接下来的
n
n
n 行,每行一个数字
x
x
x 和一个小写字母
c
h
ch
ch ,分别表示插入的位置(即插入在第
x
x
x 个字母的后面,若插入在整个单词的前面,
x
=
0
x = 0
x=0 ) ,以及你要变换的字母。
要求你输出的
n
n
n 个方案按照
x
x
x 从小到大排序,如果
x
x
x相同,那么按照
c
h
ch
ch的ASCII码从小到大排序。
解题思路
正序找不同点,逆序找不同点,比较不同点位置
AC代码
#include<bits/stdc++.h>
using namespace std;
string s,t;
int main()
{
cin>>s>>t;
int l=s.size();
int x=0,y=0;
while(x<l&&y<=l&&s[x]==t[y]) x++,y++;
int a=l-1,b=l;
while(a>=0&&b>=0&&s[a]==t[b]) a--,b--;
if(a<=x) // 倒序不同点位置小于或等于正序不同点位置
{
cout<<x-a<<'\n';
for(int i=a+1;i<=x;i++)
{
cout<<i<<' '<<t[x]<<'\n';
}
}
else cout<<"0";
return 0;
}
16进制世界
这是一个16进制的世界,比如522的16进制是20A。
在5月22日那天,有人送给Bob一些月饼,每个月饼有饱食度和幸福度两个属性。
现在Bob有 n n n个月饼,对于每个月饼 i i i,饱食度为 v i v_i vi,幸福度为 w i w_i wi。
Bob现在有 m m m饱食度,意味着他吃的月饼的饱食度之和不大于 m m m。
但是由于Bob身处16进制的世界,他吃的月饼的幸福度之和必须是16的倍数。
请帮Bob算一下他最多吃的月饼的数量。
输入描述
第一行输入两个整数
n
,
m
n,\ m
n, m
接下来 n n n行分别输入 v i , w i v_i, \ w_i vi, wi表示第 i i i个月饼的饱食度和幸福度。
输入数据保证
1
≤
n
⋅
m
≤
1
0
5
1 \leq n \cdot m \leq 10^5
1≤n⋅m≤105,
1
≤
v
i
≤
1
0
5
1 \leq v_i \leq 10^5
1≤vi≤105,
1
≤
w
i
≤
1
0
9
1 \leq w_i \leq 10^9
1≤wi≤109。
输出描述
一个整数,表示Bob最多能吃的月饼数量
解题思路
01背包,幸福度为16的倍数,利用16的余数,二维背包
AC代码
#include<bits/stdc++.h>
using namespace std;
int n,m,inf=1e9;
int main()
{
cin>>n>>m;
vector<vector<int> >f(m+1,vector<int>(16,-inf));//初始化为极小值
f[0][0]=0;
// 01背包
while(n--)
{
int v,w;cin>>v>>w;
w%=16; // 利用 16 的余数
for(int j=m;j>=v;j--)
{
for(int k=0;k<16;k++) // 遍历所有的余数
{
f[j][(k+w)%16]=max(f[j][(k+w)%16],f[j-v][k]+1);
}
}
}
int ans=0;
// 寻找体积为 i 的最大值
for(int i=0;i<=m;i++) ans=max(ans,f[i][0]);
cout<<ans;
return 0;
}
四散而逃
有一个由n个格子排成一行的走廊,边缘的格子为走廊的尽头(即 1 1 1号格子和 n n n号格子), 起初第 i i i个格子上都有 a i a_i ai个人。每次**奔逃**操作会使得同一个格子的两个人,向两侧奔逃到某个格子停下。即每次操作会选择三个下标 i , j , k i,j,k i,j,k, 其中 1 ≤ i < j < k ≤ n 1 \le i<j<k \le n 1≤i<j<k≤n ,并且 a j ≥ 2 a_j \ge 2 aj≥2 , 从 j j j号格子中选择两个人分别逃到 i i i号格子和 k k k号格子。
问最少需要多少次 ** 奔逃 ** 才能够让所有人都到达 1 1 1号格子或者 n n n号格子。若无论多少次操作都做不到,就输出`-1`
*注:应该说是二散而逃才对(o´罒`o)*
输入描述
第一行输入一个整数
n
,
(
3
≤
n
≤
2
∗
1
0
5
)
n,(3 \le n \le 2 *10^5)
n,(3≤n≤2∗105)
第二行输入n个整数
a
1
,
a
2
,
.
.
.
,
a
n
,
(
1
≤
a
i
≤
1
0
9
)
a_1,a_2,...,a_n ,(1\le a_i \le 10^9)
a1,a2,...,an,(1≤ai≤109)
输出描述
输出一个整数,表示需要最少的次数,或者-1
解题思路
分析得只要存在一个偶数(该偶数大于0),即可完成奔逃
AC代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int n,flag=0,ans=0,a;cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a;
if(i==1||i==n) continue;
if(a%2==0) flag=1;
ans=ans+(int)((a+1)/2);
}
if(flag==1) cout<<ans;
else cout<<"-1";
return 0;
}
追寻光的方向
“追寻光的方向,把你遗忘…”,听着歌,小G绕着校园在跑步。
为了简便起见,我们可以简单的认为小G在一条直线上跑步。夜晚降临,路灯在道路两旁笔直的挺立着,用自己的光驱散着黑暗。而小G要做的,就是一直追寻着最亮的那个路灯,用力向前跑去…
现已知小G所在的道路上排列着
n
n
n个路灯,由于学校电力系统的问题,每个路灯发出的光亮为
l
i
l_i
li。而小G的跑步,由于视野问题,每次只能看到前方最亮的那盏灯的位置,(若前方有多个亮度值最大,则只会跑到第一个亮度值最大的位置)所以小G每次都会全力以赴的冲到最亮的那盏灯下,然后进行一次休息。现如今小G正在第一个路灯下,请问小G如果想到达第
n
n
n个路灯下,需要休息几次?
例:如果当前路灯的亮度值分别是
4
,
3
,
5
,
7
,
1
4,3,5,7,1
4,3,5,7,1,则小G最初在亮度值为
4
4
4的路灯下,视野前方路灯值为
3
,
5
,
7
,
1
3,5,7,1
3,5,7,1其中最亮的是
7
7
7,所以小G就会跑到亮度值为
7
7
7的路灯下,然后进行休息,之后视野前方路灯值为
1
1
1,则小G跑到亮度值为
1
1
1的路灯下,也就是最后一个路灯下,完成目标,总共需要休息一次。
输入描述
第一行一个正整数,表示
n
n
n.
第二行
n
n
n个正整数,表示
n
n
n个路灯的亮度值
l
i
l_i
li
对于100%的数据,
1
≤
n
≤
1
0
5
,
1
≤
l
i
≤
1
0
9
1 \leq n \leq 10^5, 1\leq l_i\leq 10^9
1≤n≤105,1≤li≤109
输出描述
一行一个整数表示需要休息的次数。
解题思路
倒序比较较大值,每次更新,即为休息的次数
AC代码
#include<bits/stdc++.h>
using namespace std;
int a[100010];
int main()
{
int n;cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int ma=a[n],ans=0;
for(int i=n-1;i>1;i--)
if(a[i]>=ma)
{
ans++;
ma=a[i];
}
cout<<ans;
return 0;
}
等公交车
小G和朋友约好了时间出去玩,他选择坐公交车去找对方。
早早的便来到了公交站牌处开始了等公交车,但公交车却迟迟不来,终于在他濒临爆发的时候,公交车终于缓缓开来。开心的和朋友会合后,他们便开始了一天的玩乐。回到家后,小G还是对于等公交车耿耿于怀,现已知每天都会发出
m
m
m辆公交车,在手机上它可以查出这
m
m
m辆公交车的发车时刻第
t
i
t_i
ti分钟,并且他还知道所有的站点信息,总共有
n
n
n个公交车站点,第
i
i
i 个站点距离发车点的距离为
d
i
d_i
di米。已知公交车的速度为
1
1
1米/分钟,发车点和所有的站点都在一条直线上, 每次公交车从发车点出发后,依次经过每个站点。他想知道能否设计一个程序,当每次一个乘客在某个时刻时到达某个站点时,可以直接告诉他需要等待的时间?
输入描述
第一行两个个正整数,表示
n
,
m
n,m
n,m.
第二行
n
n
n个正整数,表示
n
n
n个站点距离发车点的距离
d
i
d_i
di.(数据保证
d
i
d_i
di递增)
第三行
m
m
m个正整数,表示
m
m
m辆公交车的发车时刻
t
i
t_i
ti.(数据保证
t
i
t_i
ti递增)
第四行一个正整数
Q
Q
Q,表示接下来的询问个数。
接下来 Q Q Q行,每行两个正整数 t , x t,x t,x,表示该乘客在时刻 t t t时来到了 x x x号站点。
对于100%的数据,
1
≤
n
,
m
,
q
≤
1
0
5
,
1
≤
l
i
,
t
i
≤
2
×
1
0
9
1 \leq n,m, q \leq 10^5, 1\leq l_i,t_i\leq 2\times 10^9
1≤n,m,q≤105,1≤li,ti≤2×109
输出描述
Q行,每行一个整数表示需要等待的时间,若该乘客任何公交车都无法乘上,请输出`TNT`
解题思路
每次比较 每个公交车 到该站点的时间
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int d[N],t[N];
int main()
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++) cin>>d[i];
for(int i=1;i<=m;i++) cin>>t[i];
int q;cin>>q;
while(q--)
{
int tt,x;cin>>tt>>x;
if(tt>d[x]+t[m]) cout<<"TNT\n";
else
for(int i=1;i<=m;i++)
if(d[x]+t[i]>=tt)
{
cout<<d[x]+t[i]-tt<<'\n';
break;
}
}
return 0;
}
24点
在扑克牌中有种玩法叫做24点,目标是用给定的四张牌通过基本的数学运算(加、减、乘、除)得到24。24点的玩法规则如下:
1. 准备一副扑克牌,去掉大小王,使用 `A,2,3,4,5,6,7,8,9,10,J,Q,K` 分别表示 `1,2,3,4,5,6,7,8,9,10,11,12,13`。每种各四张,共52张牌。
2. 每次从这些牌中任意取出四张牌。
3. 使用这四张牌的数字,通过加法、减法、乘法和除法运算,最终得到24。(除法是正常的数学除法,即有可能出现除不尽的情况,比如
1
÷
3
=
1
3
1\div 3=\dfrac13
1÷3=31)
4. 每张牌只能使用一次,可以任意调换数字的顺序,可以使用任意的括号来改变运算顺序。
5. 玩家需要找到至少一种解决方案。如果无法用四张牌得到24点,则说明没有解。
现在需要你判断某种情况下是否有解。
输出描述
第一行一个正整数
T
T
T
(
1
≤
T
≤
1000
)
(1\le T\le 1000)
(1≤T≤1000),表示数据的组数。
接下来
T
T
T 行,每行四个字符串,表示取出的四张牌的点数,输入的扑克牌点数只会出现 `A,2,3,4,5,6,7,8,9,10,J,Q,K`。
输入描述
输出一行一个字符串,如果有解输出 `YES`,无解输出 `NO`
解题思路
深搜,每次选择两个数进行数学运算(加、减、乘、除),最后剩余一个数时与24点比较
AC代码
#include<bits/stdc++.h>
using namespace std;
unordered_map<string, int>m = {
{"A", 1}, {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5},
{"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10},
{"J", 11}, {"Q", 12}, {"K", 13}
};
bool c(vector<double> n) {
if (n.size() == 1) return abs(n[0] - 24) <1e-12;
for (int i = 0; i < n.size(); ++i)
{
for (int j = 0; j < n.size(); ++j)
{
if (i != j)
{
vector<double> r;
for (int k = 0; k < n.size(); ++k)
{
if (k != i && k != j)
{
r.push_back(n[k]);
}
}
for (int op = 0; op < 4; ++op)
{
if (op < 2 && i > j) continue;
switch (op)
{
case 0: r.push_back(n[i] + n[j]); break;
case 1: r.push_back(n[i] * n[j]); break;
case 2: r.push_back(n[i] - n[j]); break;
case 3: if (n[j] != 0) r.push_back(n[i] / n[j]); break;
}
if (c(r)) return true;
r.pop_back();
}
}
}
}
return false;
}
int main() {
int t;
cin >> t;
while (t--) {
vector<double> v(4);
for (int i = 0; i < 4; ++i)
{
string s;
cin >> s;
v[i] = m[s];
}
sort(v.begin(), v.end());
do
{
if (c(v)) {
cout << "YES" << endl;
break;
}
} while (next_permutation(v.begin(), v.end()));
if (!c(v)) cout << "NO" << endl;
}
return 0;
}
正义从不打背身
*“正义之枪从不打背身”*。小x最近迷上了无畏契约,钟爱"正义"这把武器。可他使用该武器有一条原则:不击杀(打不中)背对自己的敌人。小x实力强大,对于所有直面自己的敌人都能一击毙命。
在一次游戏中。小x面前有 n n n个点位,从左往右序依次为 1 , 2 , 3 , … … , n 1,2,3,……,n 1,2,3,……,n。每个点位上都有一个敌人。
每个敌人 要么正面朝向小x,要么背面朝向小x。
小x实力强大,打算强迫这n个敌人玩 m m m轮小游戏之后再对每个人开枪。
游戏规则如下:
在第 i i i轮小游戏中,依次执行以下所有操作:
* 序号为 [ 1 , i ] [1,i] [1,i]的点位上的敌人位置改变。改变规则为: 从 1 , 2 , 3 , … … , i 1,2,3,……,i 1,2,3,……,i 变为 i , i − 1 , … … , 3 , 2 , 1 i,i-1,……,3,2,1 i,i−1,……,3,2,1(原来位于i号位置的敌人更换到1号位置,位于i-1号位置的敌人更换到2号位置……)
* 序号为 [ 1 , i ] [1,i] [1,i]的点位上的敌人原地旋转180°。
所有小游戏过后,小x想知道。目前在每个点位的敌人是否被击败。
输入描述
第一行输入两个整数
n
,
m
n,m
n,m
接下来一行输入一个仅由’P’和‘B’组成的字符串s。 s i = ′ P ′ s_i='P' si=′P′ 表示第i个点位的敌人当前正面对小x。 s i = ′ B ′ s_i='B' si=′B′表示第i个点位的敌人当前正背对小x。
对于所有数据保证:
1
≤
m
≤
n
≤
2
×
1
0
6
1\le m \le n\le 2\times 10^6
1≤m≤n≤2×106。
∣
s
∣
=
n
|s|=n
∣s∣=n
输出描述
输出一行n个整数。对于第i个数,如果目前位于第i个点位的敌人被击败则输出1,否则输出0。
AC代码
#include<bits/stdc++.h>
using namespace std;
string s,s1;
int main()
{
int n,m;cin>>n>>m;
cin>>s;
s1=s;
int j=0,k=m-1;
for(int i=m-1;i>=0;i--)
{
if((m-i)%2==1)
{
if(s[i]=='P') s1[j++]='B';
else s1[j++]='P';
}
else
{
if(s[i]=='P') s1[k--]='P';
else s1[k--]='B';
}
}
for(int i=0;i<n;i++) cout<< (string)(s1[i]=='B' ? "0 " : "1 ");
return 0;
}
koala的程序
koala设计了一个程序,首先他写了一个暴力算法,但是在他写完之后受到电脑病毒的影响而失忆。好在他的源代码和题面数据范围保留了下来(数据范围在输入描述中已经给出),但是现在仍然无法通过这个题目。由于电脑病毒的影响,题面已经消失,现在他希望你基于源代码做出优化来解决这道题。
C++代码:
#include <bits/stdc++.h>
using namespace std;
// 链表结构体定义
typedef struct node {
int id;
struct node \*next;
} \*pNode, Node;
// 循环链表头节点
pNode head;
// 按顺序删除的前n-1个节点的id构成的列表
vector<int> ans;
int main() {
// n个节点,判断值k
int n, k;
cin >> n >> k;
// 构造包含n个节点的循环链表
head = (pNode)malloc(sizeof(Node));
pNode now = head;
for (int i = 1; i <= n; ++i) {
pNode a = (pNode)malloc(sizeof(Node));
a->id = i;
now->next = a;
now = now->next;
}
now->next = head->next;
// pc为计数器
int pc = 0;
now = head;
// 当前节点的上一个节点
pNode last = nullptr;
// 程序执行到链表只剩下最后一个节点为止
while (n > 1) {
pc++;
last = now;
now = now->next;
// 当计数器pc = k时从循环链表中删除当前节点,并把被删除的节点的id添加到答案列表ans中
if (pc == k) {
last->next = now->next;
n--;
pc = 0;
ans.push\_back(now->id);
}
}
// 输出最终答案
for (auto id : ans) {
cout << id << ' ';
}
return 0;
}
输入描述
一行包合两个整数
n
,
k
(
2
≤
n
≤
3
∗
1
0
5
,
1
≤
k
≤
3
∗
1
0
5
)
n, k (2 \le n \le 3 * 10^5 , 1 \le k \le 3 * 10^5)
n,k(2≤n≤3∗105,1≤k≤3∗105)
输出描述
根据题意输出答案
输入
10 3
输出
3 6 9 2 7 1 8 5 10
解题思路
由代码和样例得,为约瑟夫环问题
AC 代码
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
deque<int> c;
for (int i = 1; i <= n; ++i) {
c.push_back(i);
}
int cur = 0;
int cnt=0;
while (!c.empty()) {
cnt++;
if(cnt==n)break;
cur = (cur + k - 1) % c.size();
cout << c[cur] << " ";
c.erase(c.begin() + cur);
}
return 0;
}