头像

以梦为马

HPU




离线:7小时前


分享 GL2

以梦为马
7小时前
glClear (GL_COLOR_BUFFER_BIT);          //清空
    glLoadIdentity();                           //将当前矩阵设为单位矩阵

    glPushMatrix();
    glColor3f (1.0, 0.0, 0.0);
    drawSquare(); 
    glPopMatrix();
    glPushMatrix();
    glTranslatef(0.0f,2.0f,0.0f);
    glScalef(3.0,0.5,1.0); 
    glColor3f (1.0, 1.0, 1.0); 
    drawSquare();                           //上面白色矩形
    glPopMatrix();

glBegin (GL_POLYGON);                   //顶点指定需要按逆时针方向
       glVertex2f (-1.0f,-1.0f);            //左下点
       glVertex2f (1.0f,-1.0f);             //右下点
       glVertex2f (1.0f, 1.0f);             //右上点
       glVertex2f (-1.0f,1.0f);             //左上点
    glEnd ( );


分享 GL

一.
1
void myDisplay(void)
{
   // 请在此添加你的代码

   glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glPointSize(3);
    glBegin(GL_POINTS);
    glColor3f(1.0f, 0.0f, 0.0f);   
    glVertex2f(-0.4f, -0.4f);
    glColor3f(0.0f, 1.0f, 0.0f);   
    glVertex2f(0.0f, 0.0f);
    glColor3f(0.0f, 0.0f, 1.0f);   
    glVertex2f(0.4f, 0.4f);
    glEnd();


    glFlush();
}

2.
void myDisplay(void)
{
   // 请在此添加你的代码
   glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f (1.0f, 1.0f, 1.0f); 
    glRectf(-0.5f, -0.5f, 0.5f, 0.5f);

    glBegin (GL_TRIANGLES);
    glColor3f (1.0f, 0.0f, 0.0f);   
    glVertex2f (0.0f, 1.0f);
    glColor3f (0.0f, 1.0f, 0.0f);   
    glVertex2f (0.8f, -0.5f);
    glColor3f (0.0f, 0.0f, 1.0f);   
    glVertex2f (-0.8f, -0.5f);
    glEnd ();

    glPointSize(3);
    glBegin (GL_POINTS);
    glColor3f (1.0f, 0.0f, 0.0f);   
    glVertex2f (-0.4f, -0.4f);
    glColor3f (0.0f, 1.0f, 0.0f);   
    glVertex2f (0.0f, 0.0f);
    glColor3f (0.0f, 0.0f, 1.0f);   
    glVertex2f (0.4f, 0.4f);
    glEnd ();

    glFlush();
}
3. void myDisplay(void)
{
   // 请在此添加你的代码
   /********** Begin ********/

    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f (1.0f, 0.0f, 0.0f); 
    glRectf(25.0, 25.0, 75.0, 75.0);

    glPointSize(10);
    glBegin (GL_POINTS);
    glColor3f (0.0f, 1.0f, 0.0f);   
    glVertex2f (0.0f, 0.0f);
    glEnd ();

    //LineDDA(0, 0, 200, 300);

    glBegin (GL_LINES);
    glColor3f (0.0f, 1.0f, 0.0f);   
    glVertex2f (100.0f, 0.0f);
    glColor3f (0.0f, 1.0f, 0.0f);   
    glVertex2f (180.0f, 240.0f);    
    glEnd ();


   /********** End **********/
    glFlush();
}
void Init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);
}
4.
void LineDDA(int x0,int y0,int x1,int y1/*,int color*/)
{
    int  x, dy, dx, y;
    float m;
    dx=x1-x0;
    dy=y1-y0;
    m=dy/dx;
    y=y0;

    glColor3f (1.0f, 1.0f, 0.0f);   
    glPointSize(1);
    for(x=x0;x<=x1; x++)
    {
        glBegin (GL_POINTS);
        glVertex2i (x, (int)(y+0.5));
        glEnd ();
        y+=m;
    }
}

void myDisplay(void)
{
   // 请在此添加你的代码
   /********** Begin ********/

   LineDDA( 0, 0, 200,300 );


   /********** End **********/
    glFlush();
}
void Init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);
}

5.
void MidPLine(int x1, int y1, int xn, int yn)
{
 // 请在此添加你的代码
    int dx, dy,dt,db,d,x,y;
    dx = xn - x1;
    dy = yn - y1;
    d = dx - 2*dy;
    dt = 2*dx - 2*dy;
    db = -2*dy;
    x = x1, y = y1;


    glColor3f(0.0f,3.0f,0.0f);
    glPointSize(1);
    glBegin(GL_POINTS);
    glVertex2i(x, y);
    glEnd;

    while(x < xn){
        if(d < 0){
            x ++;
            y ++;
            d += dt;
        }
        else{
            x ++;
            d += db;
        }
        glBegin (GL_POINTS);
        glVertex2i ((int)(x), (int)(y));
        glEnd ();

    }

    glFlush();
}

void myDisplay(void)
{
   // 请在此添加你的代码
   /********** Begin ********/
   glClearColor(0.0,0.0,0.0,0.0);
   glClear(GL_COLOR_BUFFER_BIT);
   MidPLine( 10, 50, 300, 260);


   /********** End **********/
    glFlush();
}
void Init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);
}


分享 进制转换

十进制转为二进制

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;
const int N = 1000;
int n, num;
int a[N];

int main(){
    cin >> n;
    do{  //不用while循环,可以有效处理n == 0的情况
        a[num ++] = n % 2;
        n /= 2;
    }while(n != 0);

    for(int i = num - 1; i >= 0; i --){
        cout << a[i];
    }

    return 0;
}

十进制转为十六进制

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;
const int N = 1000;
int n, num;
int a[N];
char h[17] = {'0', '1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//十六进制

int main(){
    cin >> n;
    do{  //不用while循环,可以有效处理n == 0的情况
        a[num ++] = n % 16;
        n /= 16;
    }while(n != 0);

    for(int i = num - 1; i >= 0; i --){
        int n = a[i];
        cout << h[n];
    }

    return 0;
}



以梦为马
1个月前

题目描述

你现在被困在一个三维地牢中,需要找到最快脱离的出路!

地牢由若干个单位立方体组成,其中部分不含岩石障碍可以直接通过,部分包含岩石障碍无法通过。

向北,向南,向东,向西,向上或向下移动一个单元距离均需要一分钟。

你不能沿对角线移动,迷宫边界都是坚硬的岩石,你不能走出边界范围。

请问,你有可能逃脱吗?

如果可以,需要多长时间?

输入格式

输入包含多组测试数据。

每组数据第一行包含三个整数 L,R,C 分别表示地牢层数,以及每一层地牢的行数和列数。

接下来是 L 个 R 行 C 列的字符矩阵,用来表示每一层地牢的具体状况。

每个字符用来描述一个地牢单元的具体状况。

其中, 充满岩石障碍的单元格用”#”表示,不含障碍的空单元格用”.”表示,你的起始位置用”S”表示,终点用”E”表示。

每一个字符矩阵后面都会包含一个空行。

当输入一行为”0 0 0”时,表示输入终止。

输出格式

每组数据输出一个结果,每个结果占一行。

如果能够逃脱地牢,则输出”Escaped in x minute(s).”,其中X为逃脱所需最短时间。

如果不能逃脱地牢,则输出”Trapped!”。

数据范围

1≤L,R,C≤100

输入样例:

3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0

输出样例:

Escaped in 11 minute(s).
Trapped!

C++代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cstdio>

using namespace std;
const int N = 110;

int l, r, c;
char g[N][N][N];//地图
int dis[N][N][N];//到起点的距离
int dx[] = {0, 0, 0, 0, 1, -1};
int dy[] = {0, 0, 1, -1, 0, 0};
int dz[] = {1, -1, 0, 0, 0, 0};

struct node{//结点
    int x, y, z;
};

int bfs(node &start, node &end){
    queue<node> q;
    q.push(start);
    memset(dis, -1, sizeof dis);
    dis[start.x][start.y][start.z] = 0;
    while(q.size()){
        auto t = q.front();
        q.pop();
        for(int i = 0; i < 6;  i ++){
            int x = dx[i] + t.x, y = dy[i] + t.y, z = dz[i] + t.z;
            if(x < 0 || x >= l || y < 0 || y >= r || z < 0 || z >= c) continue;//越界
            if(g[x][y][z] == '#') continue;//碰壁
            if(dis[x][y][z] != -1) continue;//已遍历过
            dis[x][y][z] = dis[t.x][t.y][t.z] + 1;
            if(x == end.x && y == end.y && z == end.z) return dis[x][y][z];
            q.push({x, y, z});
        }
    }
    return -1;
}

int main(){
//  freopen("abc.txt", "r", stdin);
    node st, ed;
    while(cin >> l >> r >> c, l || r || c){
        for(int i = 0; i < l; i ++){
            for(int j = 0; j < r; j ++){
                for(int k = 0; k < c; k ++){
                //  scanf("%c", &g[i][j][k]);
                    cin >> g[i][j][k];
                    if(g[i][j][k] == 'S') st = {i, j, k};//起点
                    else if(g[i][j][k] == 'E') ed = {i, j, k};//终点
                }
            }
        }
        int t = bfs(st, ed);
        if(t == -1) printf("Trapped!\n");
        else printf("Escaped in %d minute(s).\n", t);
    }

    return 0;
}



以梦为马
1个月前

题目描述

你有一张某海域 N×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:

.......
.##....
.##....
....##.
..####.
…###.
.......
其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 2 座岛屿。

由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。

具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

例如上图中的海域未来会变成如下样子:

.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

输入格式

第一行包含一个整数N。

以下 N 行 N 列,包含一个由字符”#”和”.”构成的 N×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。

照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。

输出格式

一个整数表示答案。

数据范围

1≤N≤1000

输入样例1:

7
.......
.##....
.##....
....##.
..####.
…###.
.......

输出样例1:

1

输入样例2:

9
.........
.##.##…
.#####…
.##.##…
.........
.##.#....
.#.###…
.#..#....
.........

输出样例2:

1

C ++ 代码

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstring>

#define x first
#define y second

using namespace std;
typedef pair<int, int> PII;
const int N = 1010;

int n;
char g[N][N];//地图
bool st[N][N];//是否被遍历过
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

//sx, sy表示初始坐标,lan和bound分别表示当前岛屿陆地和边界的数量
void bfs(int sx, int sy, int &land, int &bound){//flood fill算法
    queue<PII> q;//q表示陆地的集合
    q.push({sx, sy});//将初始位置加入队列
    st[sx][sy] = true;//初始位置已被遍历
    while(q.size()){
        auto t = q.front();
        q.pop();
        land ++;//陆地数量增1
        bool is_bound = false;
        for(int i = 0; i < 4; i ++){
            int x = dx[i] + t.x, y = dy[i] + t.y;
            if(x < 0 || x >= n || y < 0 || y >= n) continue;//越界
            if(st[x][y]) continue;//已被遍历过
            if(g[x][y] == '.'){//边界
                is_bound = true;
                continue;
            }
            q.push({x, y});//将当前点加入队列
            st[x][y] = true;//当前点已被遍历过

        }
        if(is_bound) bound ++;//边界的数量增1

    } 
}

int main(){
//  freopen("abc.txt", "r", stdin);
    cin >> n;
    for(int i = 0; i < n; i ++) scanf("%s", g[i]);

    int cnt = 0;
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < n; j ++){
            if(!st[i][j] && g[i][j] == '#'){//当前点为陆地且未被遍历
                int land = 0, bound = 0;
                bfs(i, j, land, bound);
                if(land == bound) cnt ++;//边界数量和陆地数量相等,即岛屿被淹没
            }
        }
    }

    cout << cnt << endl;

    return 0;
}




以梦为马
1个月前

题目描述

小明要做一个跑步训练。

初始时,小明充满体力,体力值计为 10000。如果小明跑步,每分钟损耗

600 的体力。如果小明休息,每分钟增加 300 的体力。体力的损耗和增加都是

均匀变化的。

小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循

环。如果某个时刻小明的体力到达 0,他就停止锻炼。

请问小明在多久后停止锻炼。为了使答案为整数,请以秒为单位输出答案。

答案中只填写数,不填写单位。

【答案提交】

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个

整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

C++ 代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

int main(){
    int energy = 10000;
    int cnt = 0;
    int res = 0;
    bool ispao = true;
    while(true){
        if(energy < 600 && ispao == true) break;//轮到跑且能量不够跑完一分钟
        if(ispao){//跑一分钟
            ispao = false;
            energy -= 600;
        }
        else{//休息一分钟
            ispao = true;
            energy += 300;
        }
        cnt ++;//跑或者休息一分钟的次数
    }

    res = cnt * 60 + energy / 10;//以秒为单位

    cout << res << endl;

    return 0;
}



以梦为马
3个月前

题目描述

给定 N 个整数 A1,A2,…AN。

请你从中选出 K 个数,使其乘积最大。

请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 1000000009 的余数。

注意,如果 X<0, 我们定义 X 除以 1000000009 的余数是负(−X)除以 1000000009 的余数,即:0−((0−x)%1000000009)
输入格式
第一行包含两个整数 N 和 K。

以下 N 行每行一个整数 Ai。

输出格式

输出一个整数,表示答案。

数据范围

1≤K≤N≤105,
−105≤Ai≤105

输入样例1:

5 3
-100000
-10000
2
100000
10000

输出样例1:

999100009

输入样例2:

5 3
-100000
-100000
-2
-100000
-100000

输出样例2:

-999999829

主要考点

贪心

主要思路

step 1. 对Ai~An排序

step 2. 分类讨论:
    1) k == n, 直接算

    2) k < n , 再分类
        1) k为偶数, 结果必然为负,分类讨论:
            a. 负数有偶数个, 则 res >= 0
            b. 负数有奇数个, 则选偶数个奇数, 则 res >= 0

        2) k为奇数, 分类讨论:
            a. 所有数均为负数, res < 0
            b. 至少存在一个非负数,先选择最大的那个,然后再从k - 1个中选(k - 1 为偶数,回到上一种情况),res >= 0

C ++ 代码

#include <iostream>
#include <algorithm>

using namespace std;
typedef long long LL;
const int N = 1e5 + 10, mod = 1000000009;

int n, k;
int a[N];

int main(){
    cin >> n >> k;
    for(int i = 0; i < n; i ++) cin >> a[i];

    sort(a, a + n);

    int res = 1, sign = 1;
    int l = 0, r = n - 1; 

    if(k % 2){  // k为奇数的情况
        res = a[r];
        r --, k --;
        if(res < 0) sign = -1;  //判断最大值的符号, sign = -1, 表示最终结果为负
    }

    while(k){
        LL x = (LL)a[l] * a[l + 1], y = (LL)a[r - 1] * a[r];
        if(x * sign > y * sign){
            res = x % mod * res % mod;
            l += 2;
        }
        else{
            res = y % mod * res % mod;
            r -= 2;
        }
        k -= 2;
    }

    printf("%d\n", res);

    return 0;
}




以梦为马
3个月前

题目描述

几个人一起出去吃饭是常有的事。

但在结帐的时候,常常会出现一些争执。

现在有 n 个人出去吃饭,他们总共消费了 S 元。

其中第 i 个人带了 ai 元。

幸运的是,所有人带的钱的总数是足够付账的,但现在问题来了:每个人分别要出多少钱呢?

为了公平起见,我们希望在总付钱量恰好为 S 的前提下,最后每个人付的钱的标准差最小。

这里我们约定,每个人支付的钱数可以是任意非负实数,即可以不是 1 分钱的整数倍。

你需要输出最小的标准差是多少。

标准差的介绍:标准差是多个数与它们平均数差值的平方平均数,一般用于刻画这些数之间的“偏差有多大”。

形式化地说,设第 i 个人付的钱为 bi 元,那么标准差为 :

输入格式

第一行包含两个整数 n、S;

第二行包含 n 个非负整数 a1, …, an。

输出格式

输出最小的标准差,四舍五入保留 4 位小数。

数据范围

1≤n≤5×105,
0≤ai,S≤109

输入样例1:

5 2333
666 666 666 666 666

输出样例1:

0.0000

输入样例2:

10 30
2 1 4 7 4 8 3 6 4 7

输出样例2:

0.7928

主要考点

贪心

核心思想

从小到大排序, 钱不够平均值则掏出当前剩余的所有钱, 不够的部分后面均摊,
当前钱够的话则掏平均值的钱即可.

C ++ 代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;
const int N = 5e5 + 10;

int n, s;
int a[N];

int main(){
    cin >> n >> s;
    for(int i = 0; i < n; i ++) cin >> a[i];

    sort(a, a + n);  //以防后面的前不够平均数但已无能补偿的情况

    double ave = 1.0 * s / n, cur_ave = ave, sum = 0;
    for(int i = 0; i < n; i ++){
        if(a[i] <= cur_ave){
            sum += (a[i] - ave) * (a[i] - ave);
            s -= a[i];
            cur_ave = 1.0 * s / (n - i - 1);
        }
        else{
            sum += (cur_ave - ave) * (cur_ave - ave);
        }
    }

    printf("%.4lf\n", sqrt(sum / n));

    return 0;
}



以梦为马
3个月前

题目描述

给定 N 个加号、M 个减号以及 N+M+1 个整数 A1,A2,⋅⋅⋅,AN+M+1,小明想知道在所有由这 N 个加号、M 个减号以及 N+M+1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个?

请你输出这个最大的结果。

例如使用 123+−,则 “23+1−” 这个后缀表达式结果是 4,是最大的。

输入格式

第一行包含两个整数 N 和 M。

第二行包含 N+M+1 个整数 A1,A2,⋅⋅⋅,AN+M+1。

输出格式

输出一个整数,代表答案。

数据范围

0≤N,M≤105,
−109≤Ai≤109

输入样例:

1 1
1 2 3

输出样例:

4

主要考点

逆波兰表达式
后序遍历二叉树
贪心

主要思想

根据负号个数分为两类:

  1. 负号个数为0
    对策: 直接将各数相加即可

  2. 负号个数大于0 (负号个数的范围为 1 ~ n + m + 1)
    对策:转化为一个负号的情况, 对各个数的绝对值求和.

易错点: 负号的个数不一定为 m

时间复杂度 ---- $O(n^2)$

C++代码

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long LL;

const int N = 2e5 + 10;

int n, m;
int a[N];

int main(){
    cin >> n >> m;
    int k = n + m + 1;
    for(int i = 0; i < k; i ++) cin >> a[i];

    LL res = 0;
    if(!m){  //0个负号, 即均为正数, 将所有数直接相加即可
        for(int i = 0; i < k; i ++){
            res += a[i];
        }
    }
    else{  //存在负号, 负号个数为 1 ~ n + m + 1, 转化为1个负号的情况, 求得最大值
        sort(a, a + k);
        res = a[k - 1] - a[0];
        for(int i = 1; i < k - 1; i ++){
            res += abs(a[i]);
        }
    }

    cout << res << endl;

    return 0;
}



以梦为马
3个月前

题目描述

假设海岸是一条无限长的直线,陆地位于海岸的一侧,海洋位于另外一侧。

每个小岛都位于海洋一侧的某个点上。

雷达装置均位于海岸线上,且雷达的监测范围为d,当小岛与某雷达的距离不超过d时,该小岛可以被雷达覆盖。

我们使用笛卡尔坐标系,定义海岸线为x轴,海的一侧在x轴上方,陆地一侧在x轴下方。

现在给出每个小岛的具体坐标以及雷达的检测范围,请你求出能够使所有小岛都被雷达覆盖所需的最小雷达数目。

输入格式

第一行输入两个整数n和d,分别代表小岛数目和雷达检测范围。

接下来n行,每行输入两个整数,分别代表小岛的x,y轴坐标。

同一行数据之间用空格隔开。

输出格式

输出一个整数,代表所需的最小雷达数目,若没有解决方案则所需数目输出“-1”。

数据范围

1≤n≤1000

输入样例:

3 2
1 2
-3 1
2 1

输出样例:

2

主要考点

区间选点
贪心

C++代码

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;
const int N = 1010;

int n, d;

struct Seg{
    double l, r;
    bool operator < (const Seg & s) const{
        return r < s.r;  //按按右端点进行排序
    }
}seg[N];

int main(){
    cin >> n >> d;

    bool failed = false;  //是否合法
    for(int i = 0; i < n; i ++){
        int x, y;
        cin >> x >> y;
        if(y > d) failed = true;  //不合法
        else{
            double len = sqrt(d * d - y * y);
            seg[i].l = x - len, seg[i].r = x + len;  //分别为区间的左右端点
        }
    }

    if(failed) cout << "-1" << endl;
    else{
        sort(seg, seg + n);  //将区间按照右端点进行排序

        double ed = - 2e9;
        int res = 0;
        for(int i = 0; i < n; i ++){
            if(ed < seg[i].l){
                res ++;
                ed = seg[i].r;
            }
        }
        cout << res << endl;
    }

    return 0;
}