每日一题(自存)

模拟

[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 n2
对于 50 % 50\% 50% 的数据, 0 ≤ a , b , g , k ≤ 100 0 \le a, b, g, k \le 100 0a,b,g,k100
对于 100 % 100\% 100% 的数据,有 0 ≤ n ≤ 1 0 4 0 \le n \le 10^4 0n104, 0 ≤ a , b , g , k ≤ 10 5 0 \le a, b, g, k \le {10}^5 0a,b,g,k105

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+an1xn1++a1x+a0,an=0

其中, a i x i a_ix^i aixi 称为 i i i 次项, a i a_i ai 称为 i i i 次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式:

  1. 多项式中自变量为 x x x,从左到右按照次数递减顺序给出多项式。

  2. 多项式中只包含系数不为 0 0 0 的项。

  3. 如果多项式 n n n 次项系数为正,则多项式开头不出 + 号,如果多项式 n n n 次项系数为负,则多项式以 - 号开头。

  4. 对于不是最高次的项,以 + 号或者 - 号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于 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,则仅需输出系数即可。

  5. 多项式中,多项式的开头、结尾不含多余的空格。

  • 输入格式

输入共有 2 2 2

第一行 1 1 1 个整数, n n n,表示一元多项式的次数。

第二行有 n + 1 n+1 n+1 个整数,其中第 i i i 个整数表示第 n − i + 1 n-i+1 ni+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 0n100,$-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<N200,0<NA200,0<NB200

#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)

  1. ( K − 1 ) (K-1) (K1) 在第一行但不在最后一列,则将 K K K 填在最后一行, ( K − 1 ) (K-1) (K1) 所在列的右一列;
  2. ( K − 1 ) (K-1) (K1) 在最后一列但不在第一行,则将 K K K 填在第一列, ( K − 1 ) (K-1) (K1) 所在行的上一行;
  3. ( K − 1 ) (K-1) (K1) 在第一行最后一列,则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的正下方;
  4. ( K − 1 ) (K-1) (K1) 既不在第一行,也不在最后一列,如果 ( K − 1 ) (K-1) (K1) 的右上方还未填数,则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的右上方,否则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的正下方。

现给定 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 1N39 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 1n100,1m100

#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 1n,m500,满足 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 1xrx+rn,1yry+rn

在这里插入图片描述

#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(1N103) 个堡垒需要补给, 然而总的预算 B ( 1 ≤ B ≤ 1 0 9 ) B\left(1 \leq B \leq 10^9\right) B(1B109) 是有限的。

现在已知第 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(1N103,1B109) ;第 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)(0P(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} (XiXj)2+(YiYj)2+(ZiZj)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 1N50000,答案的范围在 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 1s<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;
}
  • 43
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值