每日一题
模拟
[NOIP2011 提高组] 铺地毯
- 题目描述
为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n n n 张地毯,编号从 1 1 1 到 n n n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。
- 输入格式
输入共 n + 2 n + 2 n+2 行。
第一行,一个整数 n n n,表示总共有 n n n 张地毯。
接下来的 n n n 行中,第 i + 1 i+1 i+1 行表示编号 i i i 的地毯的信息,包含四个整数 a , b , g , k a ,b ,g ,k a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标 ( a , b ) (a, b) (a,b) 以及地毯在 x x x 轴和 y y y 轴方向的长度。
第 n + 2 n + 2 n+2 行包含两个整数 x x x 和 y y y,表示所求的地面的点的坐标 ( x , y ) (x, y) (x,y)。
- 输出格式
输出共
1
1
1 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出 -1
。
-
样例 #1
-
样例输入 #1
3
1 0 2 3
0 2 3 3
2 1 3 3
2 2
- 样例输出 #1
3
-
样例 #2
-
样例输入 #2
3
1 0 2 3
0 2 3 3
2 1 3 3
4 5
- 样例输出 #2
-1
提示
- 【样例解释 1】
如下图, 1 1 1 号地毯用实线表示, 2 2 2 号地毯用虚线表示, 3 3 3 号用双实线表示,覆盖点 ( 2 , 2 ) (2,2) (2,2) 的最上面一张地毯是 3 3 3 号地毯。
- 【数据范围】
对于
30
%
30\%
30% 的数据,有
n
≤
2
n \le 2
n≤2。
对于
50
%
50\%
50% 的数据,
0
≤
a
,
b
,
g
,
k
≤
100
0 \le a, b, g, k \le 100
0≤a,b,g,k≤100。
对于
100
%
100\%
100% 的数据,有
0
≤
n
≤
1
0
4
0 \le n \le 10^4
0≤n≤104,
0
≤
a
,
b
,
g
,
k
≤
10
5
0 \le a, b, g, k \le {10}^5
0≤a,b,g,k≤105。
noip2011 提高组 day1 第 1 1 1 题。
#include <iostream>
using namespace std;
// 定义结构体Carpet,包含地毯的信息
struct Carpet
{
int a, b, g, k, id; // 地毯的左下角坐标(a, b),宽度g,高度k,以及地毯的id
};
int main()
{
int n;
cin >> n; // 输入地毯的数量n
Carpet carpets[n+1]; // 从下标1开始,定义n个地毯
// 依次输入每块地毯的信息,并为每块地毯分配一个id
for (int i = 1; i <= n; i++)
{
cin >> carpets[i].a >> carpets[i].b >> carpets[i].g >> carpets[i].k; // 输入地毯的左下角坐标和尺寸
carpets[i].id = i; // 为地毯分配id
}
int x, y;
cin >> x >> y; // 输入坐标点x和y
int top_carpet = -1; // 初始化顶部地毯id为-1
// 从最后一块地毯开始遍历地毯数组
for (int i = n; i >= 1; i--)
{
// 判断坐标点是否在第i块地毯上,如果在,则更新顶部地毯id为当前地毯id,并终止循环
if (x >= carpets[i].a && x <= carpets[i].a + carpets[i].g && y >= carpets[i].b && y <= carpets[i].b + carpets[i].k)
{
top_carpet = carpets[i].id;
break;
}
}
// 输出位于坐标点上方的地毯id
cout << top_carpet << endl;
return 0;
}
[NOIP2009 普及组] 多项式输出
- 题目描述
一元 n n n 次多项式可用如下的表达式表示:
f ( x ) = a n x n + a n − 1 x n − 1 + ⋯ + a 1 x + a 0 , a n ≠ 0 f(x)=a_nx^n+a_{n-1}x^{n-1}+\cdots +a_1x+a_0,a_n\ne 0 f(x)=anxn+an−1xn−1+⋯+a1x+a0,an=0
其中, a i x i a_ix^i aixi 称为 i i i 次项, a i a_i ai 称为 i i i 次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式:
-
多项式中自变量为 x x x,从左到右按照次数递减顺序给出多项式。
-
多项式中只包含系数不为 0 0 0 的项。
-
如果多项式 n n n 次项系数为正,则多项式开头不出
+
号,如果多项式 n n n 次项系数为负,则多项式以-
号开头。 -
对于不是最高次的项,以
+
号或者-
号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于 0 0 0 次的项,其系数的绝对值为 1 1 1,则无需输出 1 1 1)。如果 x x x 的指数大于 1 1 1,则接下来紧跟的指数部分的形式为“ x b x^b xb”,其中 b b b 为 x x x 的指数;如果 x x x 的指数为 1 1 1,则接下来紧跟的指数部分形式为 x x x;如果 x x x 的指数为 0 0 0,则仅需输出系数即可。 -
多项式中,多项式的开头、结尾不含多余的空格。
- 输入格式
输入共有 2 2 2 行
第一行 1 1 1 个整数, n n n,表示一元多项式的次数。
第二行有 n + 1 n+1 n+1 个整数,其中第 i i i 个整数表示第 n − i + 1 n-i+1 n−i+1 次项的系数,每两个整数之间用空格隔开。
- 输出格式
输出共 1 1 1 行,按题目所述格式输出多项式。
-
样例 #1
-
样例输入 #1
5
100 -1 1 -3 0 10
- 样例输出 #1
100x^5-x^4+x^3-3x^2+10
-
样例 #2
-
样例输入 #2
3
-50 0 0 1
- 样例输出 #2
-50x^3+1
- 提示
NOIP 2009 普及组 第一题
对于100%数据, 0 ≤ n ≤ 100 0 \le n \le 100 0≤n≤100,$-100 \le 系数 系数 系数 \le 100$
upd 2022.8.1 \text{upd 2022.8.1} upd 2022.8.1:新增加一组 Hack 数据。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, a;
cin >> n;
for (int i = n; i >= 0; i--)
{
cin >> a;
if (a)
{
//判0系数
if (i != n && a > 0)
cout << "+";
//根据正负、是否为最高此项决定加号
if (abs(a) > 1 || i == 0)
cout << a;
//输出系数(系数不为正负1或指数为0)
if (a == -1 && i)
cout << "-";
//-1系数特判,常数项已特判 if (i > 1) cout << "x^" << i;
//二次及以上输出指数
if (i == 1)
cout << "x";
//一次项
}
}
}
[NOIP2014 提高组] 生活大爆炸版石头剪刀布
- 题目背景
NOIP2014 提高组 D1T1
- 题目描述
石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第 8 集中出现了一种石头剪刀布的升级版游戏。
升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:
斯波克:《星际迷航》主角之一。
蜥蜴人:《星际迷航》中的反面角色。
这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。
现在,小 A 和小 B 尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小 A 以 石头-布-石头-剪刀-蜥蜴人-斯波克
长度为
6
6
6 的周期出拳,那么他的出拳序列就是 石头-布-石头-剪刀-蜥蜴人-斯波克-石头-布-石头-剪刀-蜥蜴人-斯波克-...
,而如果小 B 以 剪刀-石头-布-斯波克-蜥蜴人
长度为
5
5
5 的周期出拳,那么他出拳的序列就是 剪刀-石头-布-斯波克-蜥蜴人-剪刀-石头-布-斯波克-蜥蜴人-...
。
已知小 A 和小 B 一共进行 N N N 次猜拳。每一次赢的人得 1 1 1 分,输的得 0 0 0 分;平局两人都得 0 0 0 分。现请你统计 N N N 次猜拳结束之后两人的得分。
- 输入格式
第一行包含三个整数: N , N A , N B N,N_A,N_B N,NA,NB,分别表示共进行 N N N 次猜拳、小 A 出拳的周期长度,小 B 出拳的周期长度。数与数之间以一个空格分隔。
第二行包含
N
A
N_A
NA 个整数,表示小 A 出拳的规律,第三行包含
N
B
N_B
NB 个整数,表示小 B 出拳的规律。其中,
0
0
0 表示 剪刀
,
1
1
1 表示 石头
,
2
2
2 表示 布
,
3
3
3 表示 蜥蜴人
,
4
4
4 表示 斯波克
。数与数之间以一个空格分隔。
- 输出格式
输出一行,包含两个整数,以一个空格分隔,分别表示小 A、小 B 的得分。
-
样例 #1
-
样例输入 #1
10 5 6
0 1 2 3 4
0 3 4 2 1 0
- 样例输出 #1
6 2
-
样例 #2
-
样例输入 #2
9 5 5
0 1 2 3 4
1 0 3 2 4
- 样例输出 #2
4 4
提示
对于 100 % 100\% 100% 的数据, 0 < N ≤ 200 , 0 < N A ≤ 200 , 0 < N B ≤ 200 0 < N \leq 200, 0 < N_A \leq 200, 0 < N_B \leq 200 0<N≤200,0<NA≤200,0<NB≤200 。
#include <iostream>
using namespace std;
const int N = 205;
int arr[5][5] = {0, -1, 1, 1, -1,
1, 0, -1, 1, -1,
-1, 1, 0, -1, 1,
-1, -1, 1, 0, 1,
1, 1, -1, -1, 0};
//打表
// 0表示平局,1表示小A胜,-1表示小B胜
int n, na, nb;
int ans1;
int ans2;
int main()
{
cin >> n >> na >> nb;
int a[N];
int b[N];
for (int i = 1; i <= na; i++)
{
cin >> a[i];
}
for (int i = 1; i <= nb; i++)
{
cin >> b[i];
}
int pointa = 1;
int pointb = 1;
for (int i = 1; i <= n; i++)
{
if (arr[a[pointa]][b[pointb]] == 1)
{
ans1++;
}
else if (arr[a[pointa]][b[pointb]] == -1)
{
ans2++;
}
pointa++; // 指针右移
pointb++;//指针左移
if (pointa > na)
{
pointa = 1;
}
if (pointb > nb)
{
pointb = 1;
}
}
cout << ans1 << ' ' << ans2;
return 0;
}
六一晚餐(蓝桥算法赛)
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int main()
{
int t;
cin >> t;
int n, m, k, a[N];
while (t--)
{
cin >> n >> m >> k;
for (int i = 1; i <= m; i++)
cin >> a[i];
bool flag = true; // 判断是否可以
int cnt = 0; // 计数椅子可配座子数量
// 因为每种中颜色必须被使用,所以可以根据椅子种类和桌子数量比较
if (n == m)
{ // 当桌子数量与椅子种类相同时,直接判断每个种类是否数量可以满足人数
for (int i = 1; i <= m; i++)
if (a[i] < k)
flag = false;
}
if (n < m)
flag = false; // 桌子数量小于椅子种类,根据条件二直接判否
if (n > m)
{
for (int i = 1; i <= m; i++)
{
if (a[i] < k)
flag = false; // 看每种椅子是否可以被用到(本人漏了这点导致错了两次)
if (a[i] > k)
cnt += a[i] / k; // 看每种椅子能适配多少个桌子
}
if (cnt < n)
flag = false; // 数量判断
}
if (flag)
cout << "Yes" << "\n";
else
cout << "No" << "\n";
}
return 0;
}
NOIP2016 提高组 D1T1
// 引入一个包含大部分标准库的头文件,用于简化代码
#include<bits/stdc++.h>
// 使用标准命名空间,以便不需要为标准库中的函数和对象指定std::前缀
using namespace std;
// 定义一个结构体node,用于存储每个位置的信息
struct node
{
int head; // 表示玩具小人的朝向,0表示朝内,1表示朝外
string name; // 该位置的名称
}a[100005]; // 定义一个包含100005个node结构体的数组,用于存储所有位置的信息
int n,m,x,y; // 声明全局变量,n表示位置数量,m表示指令数量,x和y用于存储每次输入的指令参数
int main()
{
// 输入位置数量n和指令数量m
cin>>n>>m;
// 循环n次,输入每个位置的朝向和名称
for(int i=0;i<n;i++)
{
cin>>a[i].head>>a[i].name;
}
// 初始化玩具小人的当前位置为0(索引从0开始,但实际位置可能从1开始)
int now=0;
// 循环m次,根据指令移动玩具小人
for(int i=1;i<=m;i++)
{
// 输入指令参数x和y
cin>>x>>y;
// 如果玩具小人当前朝内(head=0)且指令是向左数(x=0),则玩具小人逆时针移动y个位置
if(a[now].head==0&&x==0)now=(now+n-y)%n;
// 如果玩具小人当前朝内且指令是向右数(x=1),则玩具小人顺时针移动y个位置
else if(a[now].head==0&&x==1)now=(now+y)%n;
// 如果玩具小人当前朝外(head=1)且指令是向左数(x=0),则玩具小人顺时针移动y个位置(因为朝外时向左是顺时针)
else if(a[now].head==1&&x==0)now=(now+y)%n;
// 如果玩具小人当前朝外且指令是向右数(x=1),则玩具小人逆时针移动y个位置(因为朝外时向右是逆时针)
else if(a[now].head==1&&x==1)now=(now+n-y)%n;
}
// 输出玩具小人最后所在位置的名称
cout<<a[now].name<<endl;
return 0; // 程序正常结束
}
[NOIP2015 提高组] 神奇的幻方
- 题目背景
NOIp2015 提高组 Day1T1
- 题目描述
幻方是一种很神奇的 N × N N\times N N×N 矩阵:它由数字 1 , 2 , 3 , ⋯ ⋯ , N × N 1,2,3,\cdots \cdots ,N \times N 1,2,3,⋯⋯,N×N 构成,且每行、每列及两条对角线上的数字之和都相同。
当 N N N 为奇数时,我们可以通过下方法构建一个幻方:
首先将 1 1 1 写在第一行的中间。
之后,按如下方式从小到大依次填写每个数 K ( K = 2 , 3 , ⋯ , N × N ) K \ (K=2,3,\cdots,N \times N) K (K=2,3,⋯,N×N) :
- 若 ( K − 1 ) (K-1) (K−1) 在第一行但不在最后一列,则将 K K K 填在最后一行, ( K − 1 ) (K-1) (K−1) 所在列的右一列;
- 若 ( K − 1 ) (K-1) (K−1) 在最后一列但不在第一行,则将 K K K 填在第一列, ( K − 1 ) (K-1) (K−1) 所在行的上一行;
- 若 ( K − 1 ) (K-1) (K−1) 在第一行最后一列,则将 K K K 填在 ( K − 1 ) (K-1) (K−1) 的正下方;
- 若 ( K − 1 ) (K-1) (K−1) 既不在第一行,也不在最后一列,如果 ( K − 1 ) (K-1) (K−1) 的右上方还未填数,则将 K K K 填在 ( K − 1 ) (K-1) (K−1) 的右上方,否则将 K K K 填在 ( K − 1 ) (K-1) (K−1) 的正下方。
现给定 N N N ,请按上述方法构造 N × N N \times N N×N 的幻方。
- 输入格式
一个正整数 N N N,即幻方的大小。
- 输出格式
共 N N N 行,每行 N N N 个整数,即按上述方法构造出的 N × N N \times N N×N 的幻方,相邻两个整数之间用单空格隔开。
-
样例 #1
-
样例输入 #1
3
- 样例输出 #1
8 1 6
3 5 7
4 9 2
- 提示
对于 100 % 100\% 100% 的数据,对于全部数据, 1 ≤ N ≤ 39 1 \leq N \leq 39 1≤N≤39 且 N N N 为奇数。
#include<bits/stdc++.h>
using namespace std;
int N;
int a[40][40]; // 用来存储幻方的二维数组
int h, l; // 分别表示当前要填充的数的行和列位置
int main(){
// 输入幻方的大小
cin >> N;
// 初始化幻方,将数字1放在第一行的中间位置
a[0][N/2] = 1;
h = 0; // 初始位置为第一行
l = N/2; // 初始位置为中间列
// 从2开始填充幻方
for(int i = 2; i <= N*N; i++){
// 规则1:如果当前位置在第一行但不在最后一列,则向下移动一列
if(h == 0 && l != N-1){
a[N-1][l+1] = i;
h = N-1;
l++;
}
// 规则2:如果当前位置在最后一列但不在第一行,则向左移动一行
else if(l == N-1 && h != 0){
a[h-1][0] = i;
h--;
l = 0;
}
// 规则3:如果当前位置在第一行且最后一列,则直接向下移动一行
else if(h == 0 && l == N-1){
a[h+1][l] = i;
h++;
}
// 规则4:如果既不在第一行也不在最后一列
else if(h != 0 && l != N-1){
// 如果当前位置的右上方没有数,则向右上方填充
if(a[h-1][l+1] == 0 && h-1 >= 0 && l+1 <= N-1){
a[h-1][l+1] = i;
h--;
l++;
}
// 否则,直接向下填充
else{
a[h+1][l] = i;
h++;
}
}
}
// 输出幻方
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++) cout << a[i][j] << ' ';
cout << endl; // 换行
}
return 0; // 主函数返回0,表示程序正常结束
}
[NOIP2015 普及组] 扫雷游戏
- 题目背景
NOIP2015 普及组 T2
- 题目描述
扫雷游戏是一款十分经典的单机小游戏。在 n n n 行 m m m 列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。
现在给出 n n n 行 m m m 列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。
注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。
- 输入格式
第一行是用一个空格隔开的两个整数 n n n 和 m m m,分别表示雷区的行数和列数。
接下来 n n n 行,每行 m m m 个字符,描述了雷区中的地雷分布情况。字符 * \texttt{*} * 表示相应格子是地雷格,字符 ? \texttt{?} ? 表示相应格子是非地雷格。相邻字符之间无分隔符。
- 输出格式
输出文件包含 n n n 行,每行 m m m 个字符,描述整个雷区。用 * \texttt{*} * 表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。
-
样例 #1
-
样例输入 #1
3 3
*??
???
?*?
- 样例输出 #1
*10
221
1*1
-
样例 #2
-
样例输入 #2
2 3
?*?
*??
- 样例输出 #2
2*1
*21
- 提示
对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 100 , 1 ≤ m ≤ 100 1≤n≤100, 1≤m≤100 1≤n≤100,1≤m≤100。
#include <iostream>
#include <string>
using namespace std;
const int N = 110;
int n, m;
int dx[8] = {-1, 1, 0, 0, -1, -1, 1, 1}, dy[8] = {0, 0, -1, 1, -1, 1, -1, 1};
//打表对应格子上面的八个方向
char map[N][N];//存储雷区的图表
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> map[i][j];
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (map[i][j] == '?')
{
int sum = 0;
for (int k = 0; k < 8; k++)//对八个方向进行遍历,并且要求不超过边界
{
int x = i + dx[k], y = j + dy[k];
if (x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] == '*')
{
sum++;
}
}
map[i][j] = '0' + sum; // 将整数sum加上字符'0'的ASCII值,从而将其转换成对应的字符。
/*需要注意的是,如果sum大于9,即超出了单个数字字符的表示范围,你可能需要将sum转换为字符串(例如,使用std::to_string(sum)),但这在你的代码中是不必要的,因为sum的值始终在0到8之间。*/
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cout << map[i][j];
}
cout << endl;
}
return 0;
}
[1007] 魔法少女小Scarlet
- 题目描述
Scarlet 最近学会了一个数组魔法,她会在 n × n n\times n n×n 二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转 9 0 ∘ 90^\circ 90∘。
首先,Scarlet 会把 1 1 1 到 n 2 n^2 n2 的正整数按照从左往右,从上至下的顺序填入初始的二维数组中,然后她会施放一些简易的魔法。
Scarlet 既不会什么分块特技,也不会什么 Splay 套 Splay,她现在提供给你她的魔法执行顺序,想让你来告诉她魔法按次执行完毕后的二维数组。
- 输入格式
第一行两个整数 n , m n,m n,m,表示方阵大小和魔法施放次数。
接下来 m m m 行,每行 4 4 4 个整数 x , y , r , z x,y,r,z x,y,r,z,表示在这次魔法中,Scarlet 会把以第 x x x 行第 y y y 列为中心的 2 r + 1 2r+1 2r+1 阶矩阵按照某种时针方向旋转,其中 z = 0 z=0 z=0 表示顺时针, z = 1 z=1 z=1 表示逆时针。
- 输出格式
输出 n n n 行,每行 n n n 个用空格隔开的数,表示最终所得的矩阵
-
样例 #1
-
样例输入 #1
5 4
2 2 1 0
3 3 1 1
4 4 1 0
3 3 2 1
- 样例输出 #1
5 10 3 18 15
4 19 8 17 20
1 14 23 24 25
6 9 2 7 22
11 12 13 16 21
- 提示
对于50%的数据,满足 r = 1 r=1 r=1
对于100%的数据 1 ≤ n , m ≤ 500 1\leq n,m\leq500 1≤n,m≤500,满足 1 ≤ x − r ≤ x + r ≤ n , 1 ≤ y − r ≤ y + r ≤ n 1\leq x-r\leq x+r\leq n,1\leq y-r\leq y+r\leq n 1≤x−r≤x+r≤n,1≤y−r≤y+r≤n。
#include <iostream>
using namespace std;
const int N = 510;
int n, m;
int a[N][N];
void turn(int x, int y, int r, int z)
{
int b[510][510];//使用临时数组存储值
for (int i = x - r; i <= x + r; i++)
{
for (int j = y - r; j <= y + r; j++)
{
if (z == 0)//顺时针
{
b[i][j] = a[x + y - j][y - x + i];
}
else//逆时针
{
b[i][j] = a[x - y + j][x + y - i];
}
}
}
for (int i = x - r; i <= x + r; i++)
{
for (int j = y - r; j <= y + r; j++)
{
a[i][j] = b[i][j];//使得原数组变换成旋转后的值
}
}
}
int main()
{
int mark = 1;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
a[i][j] = mark++;
}
}
int x, y, r, z;
for (int i = 1; i <= m; i++)
{
cin >> x >> y >> r >> z;
turn(x, y, r, z);//进行旋转操作
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}
BD202401・补给(百度之星)
时间限制: 1秒
占用内存:
64
M
64 \mathrm{M}
64M
可怕的战争发生了, 小度作为后勒保障工作人员, 也要为了保卫国家而努力。
现在有
N
(
1
≤
N
≤
1
0
3
)
N\left(1 \leq N \leq 10^3\right)
N(1≤N≤103) 个堡垒需要补给, 然而总的预算
B
(
1
≤
B
≤
1
0
9
)
B\left(1 \leq B \leq 10^9\right)
B(1≤B≤109) 是有限的。
现在已知第
i
i
i 个堡砝需要价值
P
(
i
)
P(i)
P(i) 的补给, 并且需要
S
(
i
)
S(i)
S(i) 的运费。
鉴于小度与供应商之间长期稳定的合作关系, 供应商慷慨地提供了一次特别的采购优惠。具体而言, 小度可以选择对某次补给进行半价采购。
这意味着, 如果小度决定在向第
i
i
i 个堡垒提供补给时利用这一优惠, 那么此次补给的采购及运输总费用将减少至
⌊
P
(
i
)
/
2
⌋
+
S
(
i
)
\lfloor P(i) / 2\rfloor+S(i)
⌊P(i)/2⌋+S(i) , 其中优惠价格按照向下取整的原则计算。
对于其他堡垒
j
j
j, 补给的采购和运输费用则保持不变, 即
P
(
j
)
+
S
(
j
)
P(j)+S(j)
P(j)+S(j) 。
请计算小度的最多能给多少堡垒提供补给?
格式
输入格式: 第 1 行 2 个整数: N N N 和 B ∘ ( 1 ≤ N ≤ 1 0 3 , 1 ≤ B ≤ 1 0 9 ) B \circ\left(1 \leq N \leq 10^3, 1 \leq B \leq 10^9\right) B∘(1≤N≤103,1≤B≤109) ;第 2 到 N + 1 N+1 N+1 行: 第 i + 1 i+1 i+1 行包含两个空格分隔的整数, P ( i ) P(i) P(i) 和 S ( i ) 。 ( 0 ≤ P ( i ) , S ( i ) ≤ 1 0 ∘ ) S(i) 。\left(0 \leq P(i), S(i) \leq 10^{\circ}\right) S(i)。(0≤P(i),S(i)≤10∘) 。
输出格式: 1 行 1 个整数表示能提供补给的最大数。
样例 1
输入:
529
63
28
102
12
125
\begin{aligned} & \text { 输入: } 529 \\ & 63 \\ & 28 \\ & 102 \\ & 12 \\ & 125 \\ & \end{aligned}
输入: 529632810212125
输出: 4
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e3+10;
int n,b;
int s[N],p[N];
int t[N];//总和
int ans;
int main( )
{
cin>>n>>b;
for(int i=1;i<=n;i++)
{
cin>>s[i]>>p[i];
}
//暴力枚举每一个优惠的情况
for(int i=1;i<=n;i++)
{
t[i]=s[i]/2+p[i];
for(int j=1;j<=n;j++)
{
if(i==j)
{
continue;
}
t[j]=s[j]+p[j];
}
sort(t+1,t+1+n);
for(int k=1;k<=n;k++)
{
if(b<t[k])
{
ans=max(ans,k-1);
break;
}
else
{
b-=t[k];
}
}
}
cout<<ans;
return 0;
}
排序
攀爬者
- 题目背景
HKE 考完 GDOI 之后跟他的神犇小伙伴们一起去爬山。
- 题目描述
他在地形图上标记了 N N N 个点,每个点 P i P_i Pi 都有一个坐标 ( x i , y i , z i ) (x_i,y_i,z_i) (xi,yi,zi)。所有点对中,高度值 z z z 不会相等。HKE 准备从最低的点爬到最高的点,他的攀爬满足以下条件:
(1) 经过他标记的每一个点;
(2) 从第二个点开始,他经过的每一个点高度 z z z 都比上一个点高;
(3) HKE 会飞,他从一个点 P i P_i Pi 爬到 P j P_j Pj 的距离为两个点的欧几里得距离。即, ( X i − X j ) 2 + ( Y i − Y j ) 2 + ( Z i − Z j ) 2 \sqrt{(X_i-X_j)^2+(Y_i-Y_j)^2+(Z_i-Z_j)^2} (Xi−Xj)2+(Yi−Yj)2+(Zi−Zj)2
现在,HKE 希望你能求出他攀爬的总距离。
- 输入格式
第一行,一个整数 N N N 表示地图上的点数。
接下来 N N N 行,三个整数 x i , y i , z i x_i,y_i,z_i xi,yi,zi 表示第 i i i 个点的坐标。
- 输出格式
一个实数,表示 HKE 需要攀爬的总距离(保留三位小数)
-
样例 #1
-
样例输入 #1
5
2 2 2
1 1 1
4 4 4
3 3 3
5 5 5
- 样例输出 #1
6.928
- 提示
对于100%的数据, 1 ≤ N ≤ 50000 1\leq N\leq 50000 1≤N≤50000,答案的范围在 double 范围内。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10;
int n;
pair<int, pair<int, int>> p[N];//点对(z,x,y)这样我们可以完成对z的排序
double sum;//攀爬的总距离
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> p[i].second.first >> p[i].second.second >> p[i].first;
}
sort(p + 1, p + 1 + n);//根据输入的值对z进行排序
for (int i = 2; i <= n; i++)
{
double route = fabs((p[i].first - p[i - 1].first) * (p[i].first - p[i - 1].first)) + fabs((p[i].second.first - p[i - 1].second.first) * (p[i].second.first - p[i - 1].second.first)) + fabs((p[i].second.second - p[i - 1].second.second) * (p[i].second.second - p[i - 1].second.second));//欧几里得
sum = sum + sqrt(route);
}
printf("%.3lf\n", sum);
return 0;
}
生日
- 题目描述
cjf 君想调查学校 OI 组每个同学的生日,并按照年龄从大到小的顺序排序。但 cjf 君最近作业很多,没有时间,所以请你帮她排序。
- 输入格式
输入共有 n + 1 n + 1 n+1 行,
第 1 1 1 行为 OI 组总人数 n n n;
第 2 2 2 行至第 n + 1 n+1 n+1 行分别是每人的姓名 s s s、出生年 y y y、月 m m m、日 d d d。
- 输出格式
输出共有 n n n 行,
即 n n n 个生日从大到小同学的姓名。(如果有两个同学生日相同,输入靠后的同学先输出)
-
样例 #1
-
样例输入 #1
3
Yangchu 1992 4 23
Qiujingya 1993 10 13
Luowen 1991 8 1
- 样例输出 #1
Luowen
Yangchu
Qiujingya
- 提示
数据保证, 1 < n < 100 1<n<100 1<n<100, 1 ≤ ∣ s ∣ < 20 1\leq |s|<20 1≤∣s∣<20。保证年月日实际存在,且年份 ∈ [ 1960 , 2020 ] \in [1960,2020] ∈[1960,2020]。
#include <bits/stdc++.h>
using namespace std;
int n;
struct node
{
string name;;//姓名
int y;//年月日
int m;
int d;
int id;//记输出顺序
} s[110];
bool cmp(node& a,node& b)
{
if(a.y!=b.y)//如果出生年份不相等便直接按照年份进行排序,注意是升序
{
return a.y < b.y;
}
else
{
if(a.m!=b.m)
{
return a.m<b.m;
}
else
{
if(a.d!=b.d)
{
return a.d<b.d;
}
else
{
return a.id>b.id;同年同月同日生 便把后输入的排在前面,注意是降序
}
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> s[i].name >> s[i].y >> s[i].m >> s[i].d;
s[i].id = i;
}
sort(s + 1, s + 1 + n,cmp);
for (int i = 1; i <= n; i++)
{
cout << s[i].name << endl;
}
return 0;
}