每天积累的题写写题解
☘️ 题目描述☘️
他来到了一家商店门前。这家商店为了吸引顾客来买快乐水,搞了这么一个活动: 5 5 5 个瓶盖换一瓶快乐水。于是,人们纷纷来他的店里买快乐水。
买完快乐水,他想到了一个问题:
如果一瓶快乐水有 m m m 个附属品,对于第 i i i 个附属品,每 a i a_i ai 个可以换一瓶全新的快乐水,现在我有买 n n n 瓶快乐水的钱,我最多能喝多少快乐水呢?
输入格式:
第一行两个整数 n , m n,m n,m,意义如上。
接下来一行 m m m 个整数 a 1 , a 2 , ⋯ , a m a_1,a_2,\cdots,a_m a1,a2,⋯,am,意义如上。
输出格式:
如果小 W 可以无限白嫖快乐水,那么输出一行一个字符串Inf
。
否则,输出一行一个整数 s s s,表示小 W 最多能喝的快乐水数量。
(1)已知:
1)
5
5
5瓶子快乐水盖可换一瓶快乐水 2)一瓶快乐水有
m
m
m个附属品 3)第
i
i
i个附属品即第i种附属品
,每
a
i
a_i
ai个附属品可以换一瓶快乐水
(2)可知:
1)换快乐水途径:
5
5
5个水瓶盖换 和
a
i
a_i
ai个
i
i
i种类的附属品换一瓶快乐水两种途径
(3)先将一开始可以喝的快乐水的数量进行存入总量可以喝的快乐水数量中,将当前快乐水数量也令用一个变量进行存储,进行对于快乐水按题中要求一直循环下去,将当前一轮的每一种附属品进行换快乐水的操作,直到完成所有符合条件的操作
#include
using namespace std;
int n, m;
int a[6], b[6];
long long ans = 0;
int sum = 0, summ = 0;
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d", &a[i]);
}
ans += n; //(1)
sum += n; //(2)
for (int i = 1; i <= 28000000; i++) { //(3)
for (int j = 1; j <= m; j++) { //(4)
b[i] += sum;
summ = summ + b[i] / a[i];
b[i] %= a[i];
}
if (summ >= n) { //(5)
printf ("Inf");
return 0;
}
sum = summ; //(6)
ans += summ; //(7)
summ = 0; //(8)
}
printf("%lld", ans);
return 0;
}
(1)喝掉的可乐总数
(2)上一轮的快乐水数,用于换取每一种附属品
(3)一直喝下去
(4)判断当前这一轮附属品可以换到多少快乐水
(5)获取的快乐水量大于等于开始的量,则会无限被白嫖
(6)存储上一轮水量
(7)存储入总量
(8)当前量归零
☘️ 题目背景☘️
话说absi2011的企鹅在和斗神塔第60层的Boss战斗
不好,这局要输了,企鹅还剩4血了Boss还有392呢,哇,漂亮——红缨枪连击,280,343(暴击),绝杀!嗜血(4星,嗜血50%),完胜(absi2011的60级 企鹅贫血,就315,玩过乐斗的别黑)!
☘️ 题目描述☘️
别说这是个巧合,这类绝杀还真不少。
现在假设Boss还剩下的血为x,absi2011的企鹅剩y血,它拿出的武器的伤害最高是z。它的武器有几率连击。
他问你有无可能绝杀(可连击)。如果能,请先输出一行”Yes”,不能输出”No”。如果他给你的数据是错的,请输出”Wrong Data”
数据有这么几种情况算错:y<=0或y>315或y>=x或x>1800(当前斗神塔Boss好像没有超过1800血的)或z>=1000(红缨枪+天马流星拳+会心一击+残影+武器好手好像都达不到)或z<=100(absi2011认为小于等于100就不算绝杀了)
(输出Yes后)接下来,他还想问绝杀(就算最高伤害)后如果触发他的3星嗜血/4星嗜血/5星吸星大法各能不能完胜。三星每次的嗜血嗜血量为33%*伤害(下取整),四星每次的嗜血嗜血量为50%*伤害(下取整),五星吸星大法嗜血量为100%*伤害(这还真不用下取整)。两次要分开算。如果超过血上限就不再回血了。
如果三星能就输出一行”Great”,四星能就输出一行”Eh…”和一行”OK”,五星能就输出两行”Oh…”和一行”Yes , If he can get 5-star.”
如果都不行,那么输出三行”No”和他4星嗜血后的血量。
注意,有可能打一下Boss就挂了,那么不能连击嗜血了。只能算打死Boss那下的嗜血。
输入格式
一行三个整数,x、y、z
输出格式
如题目所描述
(1)
#include
using namespace std;
int x,y,z;
bool flag=false;
int main()
{
cin>>x>>y>>z;
if(y<=0||y>315||y>=x||x>1800||z>=1000||z<=100) //(1)
cout<<"Wrong Data"<<endl;
else if(z*2<x) cout<<"No"<<endl; //(2)
else //(3)
{
cout<<"Yes"<<endl;
if(z>=x)
{
if(int(z*0.33)*1+y>=315)
{
cout<<"Great"<<endl;
flag=true;
}
else if(int(z*0.5)*1+y>=315)
{
cout<<"Eh.."<<endl<<"OK"<<endl;
flag=true;
}
else if(z+y>=315)
{
cout<<"Oh.."<<endl<<"Oh.."<<endl<<"Yes , If he can get 5-star."<<endl;
flag=true;
}
if(!flag)
{
cout<<"No"<<endl<<"No"<<endl<<"No"<<endl;
cout<<int(z*0.5)+y<<endl;
}
}
else
{
if(int(z*0.33)*2+y>=315)
{
cout<<"Great"<<endl;
flag=true;
}
else if(int(z*0.5)*2+y>=315)
{
cout<<"Eh.."<<endl<<"OK"<<endl;
flag=true;
}
else if(z*2+y>=315)
{
cout<<"Oh.."<<endl<<"Oh.."<<endl<<"Yes , If he can get 5-star."<<endl;
flag=true;
}
if(!flag)
{
cout<<"No"<<endl<<"No"<<endl<<"No"<<endl;
cout<<int(z*0.5)*2+y<<endl;
}
}
}
return 0;
}
(1)数据错误
(2)不可绝杀
(3)按题模拟
☘️ 题目描述☘️
农业,尤其是生产牛奶,是一个竞争激烈的行业。Farmer John 发现如果他不在牛奶生产工艺上有所创新,他的乳制品生意可能就会受到重创!
幸运的是,Farmer John 想出了一个好主意。他的三头获奖的乳牛,Bessie、Elsie 和 Mildred,各自产奶的口味有些许不同,他打算混合这三种牛奶调制出完美的口味。
为了混合这三种不同的牛奶,他拿来三个桶,其中分别装有三头奶牛所产的奶。这些桶可能有不同的容积,也可能并没有完全装满。然后他将桶 1 1 1 的牛奶倒入桶 2 2 2,然后将桶 2 2 2 中的牛奶倒入桶 3 3 3,然后将桶 3 3 3 中的牛奶倒入桶 1 1 1,然后再将桶 1 1 1 的牛奶倒入桶 2 2 2,如此周期性地操作,共计进行 100 100 100 次(所以第 100 100 100 次操作会是桶 1 1 1 倒入桶 2 2 2)。当 Farmer John 将桶 a a a 中的牛奶倒入桶 b b b 时,他会倒出尽可能多的牛奶,直到桶 a a a 被倒空或是桶 b b b 被倒满。
请告诉 Farmer John 当他倒了 100 100 100 次之后每个桶里将会有多少牛奶。
输入格式
输入文件的第一行包含两个空格分隔的整数:第一个桶的容积 c 1 c_1 c1,以及第一个桶里的牛奶量 m 1 m_1 m1。 c 1 c_1 c1 和 m 1 m_1 m1 均为正,并且不超过 1 0 9 10^9 109。第二和第三行类似地包含第二和第三个桶地容积和牛奶量。
输出格式
输出三行,给出倒了 100 100 100 次之后每个桶里的牛奶量。
提示
在这个例子中,每倒一次之后每个桶里的牛奶量如下:
0. 初始状态:3 4 5
1. 桶1->2:0 7 5
2. 桶2->3:0 0 12
3. 桶3->1:10 0 2
4. 桶1->2:0 10 2
5. 桶2->3:0 0 12
(之后最后三个状态循环出现……)
(1)三个桶依次倒100次,输出最后呈现的结果
#include
using namespace std;
int capacity[10], existing[10];
int main() {
for (int i = 1; i <= 3; i++) {
cin >> capacity[i] >> existing[i];
}
for (int i = 1; i <= 100; i++) {
int nindex = (i - 1) % 3 + 1, neindex; //(1)
if (nindex == 3) neindex = 1;//(2)
else neindex = nindex + 1;
int mn = min(capacity[neindex] - existing[neindex], existing[nindex]); //(3)
existing[neindex] += mn;
existing[nindex] -= mn;
}
for (int i = 1; i <= 3; i++) {
cout << existing[i] << endl;
}
return 0;
}
(1)当前数被
3
3
3取余
(2)如果是
3
3
3下一个桶子取
1
1
1,如果是其他取下一个桶子
(3)嗯,木桶效应,取最小,之后改变桶子含牛奶量大小
(4)本质上就是依次顺序倒腾
3
3
3个桶中不能超出固定含量,可以用数组进行存储;在循环中判断当前是哪个桶子的下标,需要一个变量被计算后表示,被三取余得之;而下一个桶的下标需要一个变量进行存储,若当前桶为最后一个,则特殊判断下一个桶下标为1,其他则直接在当前桶子下标的基础上进行加一;
☘️ 题目描述☘️
在一个城市,有一条笔直的公路,在这条公路上有 N N N 个十字路口,每个路口都设有一个红绿灯,已知相邻的两个路口距离为 A i A_i Ai 千米 ( 1 ≤ i < N ) (1\le i < N) (1≤i<N),每个路口的红灯时间为 R i R_i Ri,绿灯时间为 G i G_i Gi,没有黄灯,现在有一辆车从距离 1 1 1 号十字路口 M M M 千米的位置出发,且此时所有路口的红绿灯刚好从红灯跳到绿灯,问这辆车通过每个路口的时间(不能闯红灯,这辆车的速度为 1 1 1 千米每分钟)。
输入格式
第一行两个正整数 N N N 和 M M M
第二行 N − 1 N-1 N−1 个正整数 A i A_i Ai
第三行 N N N 个正整数 R i R_i Ri,为红灯时间(分钟)
第四行 N N N 个正整数 G i G_i Gi,为绿灯时间(分钟)
输出格式
共 N N N 行,每行一个正整数,为这辆车通过每个十字路口的最早时间。
(1)求每个到每个路口时的时间,同时可以以每一段路程为一个循环,并以实时的路程进行判断当前的灯是否为红灯还是绿灯,而所有路灯都是从绿灯开始的,若是绿灯直接通过开始下一轮循环,若为红灯需要把等一会的时间加入至计时器中;直到循环完毕;
#include
using namespace std;
int main() {
int n, m, a[100001], b[100001], c[100001], x = 0, k, i;
scanf("%d%d", &n,&m);
for (int i = 1; i < n; i++) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &c[i]);
}
for (int i = 1; i <= n; i++) {
if (i >= 2) { //(1)
m += a[i - 1];
}
if (c[i] < m % (b[i] + c[i])) { //(2)
m += b[i] + c[i] - m % (b[i] + c[i]);
}
printf("%d\n", m);
}
return 0;
}
(1)除第一段路程之后的路程计入计时器
(2)要等红灯的时间
(3)本质上就是实时更新通过红绿灯时的时长用一个变量进行表示,且需要判断通过红绿灯时的是红灯还是绿灯,红绿灯所处的时长是相对固定的一段,判断时因为都从绿灯开始的,所以绿灯所存在的时长处于前半段,红灯所处于的时长在后半段,整体红绿灯时长取余当前花费的时长即为当前红绿灯所处的时间段,若当前所处于时间段大于绿灯所处时间段,则将处于红灯到绿灯等待的时间进行记录入当前花费的时长中,之后输出这一时间段所处的时间点
☘️ 题目描述☘️
“不放债不借债”,贝西多么希望自己可以遵循这个忠告。她已经和她的 N ( 1 ≤ N ≤ 100 , 000 ) N(1 \leq N \leq 100,000) N(1≤N≤100,000) 个朋友有了债务关系,或者借债了,或者放债了。她的 N N N 个朋友依次标号为 1 … N 1\dots N 1…N。
结算日终于来临了。她知道,朋友欠她的钱比她欠朋友的钱多。她的朋友们分布在一条直线上,第 i i i 头奶牛站的位置距离谷仓 i i i 米。贝西打算沿着这条直线行走,从欠她钱的奶牛手里收钱回来,并且还钱给她欠钱的奶牛。 当她沿直线移动的时候,她可以要求任何欠她钱的奶牛还全部的钱。当她有足够的钱可以还清她的某个债,就可以把钱给对应的奶牛还清她的债。奶牛 i i i 欠贝西 D i D_i Di 元 ( − 1 , 000 ≤ D i ≤ 1 , 000 , D i ≠ 0 ) (-1,000 \leq D_i \leq 1,000,D_i \neq 0) (−1,000≤Di≤1,000,Di=0),负数表示贝西欠奶牛 i i i 钱。
贝西从谷仓出发,位置为 0 0 0,初始贝西没有钱。贝西收回她的所有借债,并且还清她的欠债所需行走的最短距离是多少?注意:她必须在最后一头奶牛所在的位置,完成她的行走。
输入格式
第一行,一个整数 N N N
接下来第 2 … N + 1 2 \dots N+1 2…N+1 行,第 i + 1 i+1 i+1 行包含一个整数 D i D_i Di
输出格式
一个整数,贝西收回借债并且还清欠债,所需要行走的最短距离(单位为米)
(1)一条直线一次还款和收款,若还不了款,则进行记录当时位置,然后进行,直到可以还清当前已知所有款,进行一次路程的累加,直到尽头,最后输出花费时间
#include
using namespace std;
int sum = 0, n, money[100000];
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> money[i];
}
int flag = 1; //(1)
int l;
int ret = 0;
for (int i = 1; i <= n; i++) {
ret += 1; //(2)
sum += money[i]; //(3)
if (sum >= 0 && flag == 0) { // (4)
ret = ret + (i - l) * 2;
flag = 1;
} else if (sum < 0 && flag == 1){ // (5)
l = i;
flag = 0;
}
}
cout << ret;
return 0;
}
(1)判断是否欠着之前的钱
(2) 距离增加
(3)当前所有的钱的总值
(4)若持有的钱是正数,且之前的债务没有偿还,而现在偿还了,进行累加返回还债时的数,并标明已偿还
(5)若持有的钱是负数,且还不需要还债,标记为需要还债
(6)本质上将M当前所含有的所有钱这一变量作为一个作为一个整体,判断这一数的正负属性,用专门一个变量来表示用于判断的正负属性,若为正数只单独的记录着每一循环的一次步数,若为负数,则将处于负数的位置记录下来,当前状态变量记录进行染色,直到当前所含的所有钱这一变量为正数时,将当前状态变量记录取消染色,并将之前处于负数的位置到
现在处于正数位置的距离
∗
2
*2
∗2加入总步数中;直到
f
o
r
for
for结束;
☘️ 题目描述☘️
SH的跑步成绩一直不太理想。为了帮助SH提高成绩,KC决定和他进行一次赛跑。比赛的起点设在农场主的屋前,他们同时出发,沿着同一方向,直到跑到终点----农场远处的一棵树下。
他们的跑步速度在一些时间段内是恒定的。比如:SH在前3个时间段速度是5,接着6个时间段内速度是10。他们的比赛总时间相同。他们希望能统计出在整个比赛过程中领先顺序的变化次数。举个例子,某个时刻SH领先,下个时刻KC领先,这就是一次领先顺序的变化;如果某个时刻SH领先,接下来一段时间KC赶上来并和SH齐头并进,但最终还是超过了SH,这也是一次领先顺序的变化。
输入格式
第1行:N和M(1 <= N, M <= 1000)。
接下来的N行:每行两个整数,描述SH跑步的一段,分别表示该段SH跑步的速度和持续这种速度的时间。所有的数据范围 [1…1000]。
再接下来的M行:每行两个整数,描述KC跑步的一段,分别表示该段KC跑步的速度和持续这种速度的时间。所有的数据范围 [1…1000]。
输出格式
一行:整个比赛过程中领先顺序的变化次数。
提示
输入:SH在前 2 2 2 个单位时间内速度是 1 1 1,接着 1 1 1 个单位时间内速度是 4 4 4,接着 1 1 1 个单位时间内速度是 1 1 1,最后 10 10 10 个单位时间内速度是 2 2 2。KC在前 3 3 3 个个单位时间内速度是 2 2 2,接着 2 2 2 个单位时间内速度是 2 2 2,最后 9 9 9 个单位时间内速度是 3 3 3。
输出:比赛开始后KC领先,直到第 5 5 5 个单位时间SH超过KC(第一次领先顺序变化),接着第 7 7 7 个单位时间时,KC又反超SH,变成领先(第二次领先顺序变化)。
(1)在同一起跑线上,完成的总时长是相同的,同时中途每段的时间的速度是各不相同的,求领先顺序的变化次数
(2)所以因为两人跑完总路程花费的总时长是相同的,只是有时间段速度是不同的,且每个时间段中包含的速度是连续且相同的,即可表示为两个数组的长度是相同的,且由各不相同的每一段连续的下标值所组成的一个数组;需要判断的是领先顺序的变化次数而起跑时第一时间内领先并不算,需要进行特殊判断,且判断其中一个人在这段路程上领先顺序的变化次数进行累加,分别进行一次循环后,将其输出;
#include
using namespace std;
int speed1[101000], speed2[101000]; //存储人物的速度
int len1 = 0, len2 = 0; //存储人物的距离
int length = 0; //花费的总时间长度
int main() {
int n, m; //各自输入的行数
int v, l; //速度,一段时间的值
cin >> n >> m;
int sec = 1; //一段时间的开头
for (int i = 0; i < n; i++) { //循环
cin >> v >> l;
for (int j = sec; j <= sec + l; j++) { //(1)
speed1[j] = v;
}
sec += l; //(2)
length += l; //(3)
}
sec = 1; //(4)
for (int i = 0; i < m; i++) {
cin >> v >> l;
for (int j = sec; j < sec + l; j++) {
speed2[j] = v;
}
sec += l;
}
int ret = 0; //领先顺序的变化次数
bool flag = false; //用于特殊判断是否为开始时的速度快慢使其不计入ret
for (int i = 1; i <= length; i++) { //循环总时长次
len1 += speed1[i]; //累加入
len2 += speed2[i]; //累加入
if (len1 > len2 && !flag) { //(5)
flag = true;
}
if (len2 > len1 && flag) { //(6)
flag = false;
ret++;
}
//if (len2 > len1 && !flag) {
// flag = true;
//}
//if (len1 > len2 && flag) {
// flag = false;
// ret++;
//}
}
flag = false; //(7)
len1 = 0, len2 = 0;
for (int i = 1; i <= length; i++) {
len1 += speed1[i];
len2 += speed2[i];
if (len2 > len1 && !flag) {
flag = true;
}
if (len1 > len2 && flag) {
flag = false;
ret++;
}
}
cout << ret;
return 0;
}
(1)时间点作为数组下标进行存入速度值
(2)加上当前时间段的值作为下一段时间点开头的下标
(3)记录需要花费的总时长
(4)
s
e
c
复
原
sec复原
sec复原重复
(
1
)
(1)
(1)~
(
2
)
(2)
(2)的上一次大循环
(5)判断是否为开始时的领先
(6)判断领先顺序次数
(7)重复上一次的循环
(8)本质上就是将总时长作为两个数组的下标总长度,将其构建出来,
l
l
l做为每段区域,全部值为
v
v
v,
s
e
c
+
l
sec+l
sec+l作为下一段的开头,累加构成这个数组;并用两个变量分别从两个数组下标从小到大,累加这一下标长度相同,但下标值不同的两个数组下标值,除开始一段的领先的不计入外,之后计入,再循环一次;
☘️ 题目描述☘️
一个城市遭到了 M M M 次轰炸,每次都炸了一个每条边都与边界平行的矩形。
在轰炸后,有 N N N 个关键点,指挥官想知道,它们有没有受到过轰炸,如果有,被炸了几次,最后一次是第几轮。
输入格式
第一行,两个整数: M , N M,N M,N。
以下 M M M 行,每行四个整数: x 1 x_1 x1、 y 1 y_1 y1、 x 2 x_2 x2、 y 2 y_2 y2,表示被轰炸的矩形的左上角坐标和右下角坐标(比如1 3 7 10
就表示被轰炸的地方是从 ( 1 , 3 ) (1,3) (1,3)到 ( 7 , 10 ) (7,10) (7,10) 的矩形)。
再以下 N N N 行,每行两个整数,表示这个关键点的坐标。
输出格式
共 N N N 行,
每行第一个字符为YES
或NO
,表示是否被轰炸,若为YES
,在一个空格后为两个整数,表示被炸了几次和最后一次是第几轮。
提示
1 ≤ N , M ≤ 2000 1 \le N,M\le 2000 1≤N,M≤2000
1 < = x 1 , y 1 , x 2 , y 2 < = 2 32 − 1 1<=x_1,y_1,x_2,y_2<=2^{32}-1 1<=x1,y1,x2,y2<=232−1
(1)问在M次轰炸中,一次轰炸是一个矩形;给定的N个关键点是否受到轰炸,即是否包含在矩形内部;若不在则输出
N
O
NO
NO,若在则输出被炸次数和最后一次的位置;
(2)由于直接给定每个矩阵的左上角和右下角,直接
f
o
r
for
for循环
关
键
点
数
关键点数
关键点数,然后再
f
o
r
for
for循环
所
有
轰
炸
矩
阵
所有轰炸矩阵
所有轰炸矩阵用
i
f
if
if判断关键点是否在当前矩阵中存在,存在则进行累加记录,并存储当前位置,直到对所有轰炸矩阵进行一轮循环;完毕后,如果存在累加值,输出存在时要输出的,不存在累加值输出
N
O
NO
NO,接着大循环;
#include
using namespace std;
struct matrix{ //结构体存矩阵下标
int x1, y1, x2, y2;
}a[20010];
int m, n; //轰炸次数,关键点数量
int x3, y3; //关键点坐标
int main() {
cin >> m >> n;
for (int i = 1; i <= m; i++) {
cin >> a[i].x1 >> a[i].y1 >> a[i].x2 >> a[i].y2;
}
int ret = 0, postion; //记录变量,位置变量
for (int i = 1; i <= n; i++) {
cin >> x3 >> y3;
for (int j = 1; j <= m; j++) {
if(x3 >= a[j].x1 && x3<= a[j].x2 && y3 >= a[j].y1 && y3 <= a[j].y2) { //(1)
ret++;
postion = j;
}
}
if (ret) {
printf("YES %d %d\n",ret, postion);
} else {
printf("NO\n");
}
ret = 0;
}
return 0;
}
(1)根据左上角坐标与右下角坐标作为范围判断关键点的是否在轰炸矩阵内
(2)本质上就是直接按题意模拟了一遍,利用左上标和右下标确定了矩阵范围,直接判断关键点是否包含在其中
(1)题意理解错了,以后要结合样例好好思考一下
(2)捋好好清楚各个事务及事件的关系再开始下手去实现代码
(3)提升将思路实现为具体代码的能力,抓住本质
(4)好好做草稿
(5)好好看题