SCAU c++ STL的应用

19116 丑数

时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC

Description

“丑数”是指除了质因子2,3,5,不含其它质因子的正整数,例如由小到大前10个“丑数”为
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, …
现要求编写一个程序,输出指定第几位的“丑数”。

输入格式

第一行为正整数T(T<=10000), 表示case的数目。
此后T行,每行一个正整数 n (n <= 100000000).

输出格式

每一个n,输出第n个“丑数”

输入样例

3
1
2
9

输出样例

1
2
10

#include <iostream>
using namespace std;
int main()
{
    long long n,x=1,y=1,z=1,i,a[10005];
    a[1]=1;
    for(int i=2;i<=10000;i++)
    {
        a[i]=min(a[x]*2,min(a[y]*3,a[z]*5));
        if(a[i]==a[x]*2) x++;
        if(a[i]==a[y]*3) y++;
        if(a[i]==a[z]*5) z++;
    }
    cin>>n;
    while(n--)
    {
        cin>>i;
        cout<<a[i]<<endl;

    }


    return 0;
}

18440 走迷宫

时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC;VC

Description

有一个N*M(N,M<=10)的格子迷宫,1代表该格子为墙,不能通过,0代表可以通过,人在迷宫中可以尝试上下左右四个方向移动。
另外,在迷宫中如果从左边走出迷宫会回到迷宫最右边一格(只要该格不是墙),行不变,同样,从右边走出迷宫会
回到迷宫最左边一格,向上走出迷宫会回到迷宫最下边一格,向下走出迷宫会回到迷宫最上边一格。
现在给定一个迷宫,以及起点和终点,问最少多少步可以走出迷宫。如果不能走出迷宫输出“die”。

输入格式

该程序为多CASE,第1行为CASE的数量
每一个CASE,第1行为两个数N(行)和M(列)
然后N行每行M个数,之后是起点坐标和终点坐标sc(行) sr(列) ec(行) er(列)

输出格式

如题

输入样例


2
4 3
011
010
110
110
0 0 3 2
2 2
01
10
0 0 1 1

输出样例

4
die

提示

第一个case,可以从(1,0)走到(1,2)

#include <iostream>
#include <cmath>
#include<algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 115;
typedef pair<int, int> pii;
char g[N][N];//存地图中的点是否被遍历
int f[N][N];//存距离
int n, m;
int a,b,c,d;
void bfs(int a, int b) {
	queue<pii> q;//存点的坐标
	q.push({ a,b });//起点入队
	int x=0, y=0;
	while (!q.empty()) {
		pii start = q.front();//起点赋值
		q.pop();//出队

		int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };//往上下左右四个方向移动
		for (int i = 0; i < 4; i++) {
			//当前点
			 x = start.first + dx[i], y = start.second + dy[i];
			 if(x<0)x=n-1;
			 if(x>=n)x=0;
			 if(y<0)y=m-1;
			 if(y>=m)y=0;
			//如果当前点未走过
			if (g[x][y] == '0') {
				g[x][y] = '1';
				//从当前点走过去,则距离等于当前点的距离+1.
				f[x][y] = f[start.first][start.second] + 1;
				q.push({ x,y });

			}
		}
	}
	if(f[c][d]==0)cout<<"die"<<endl;
	else cout << f[c][d]<<endl;
	
}
int main() {
	ios::sync_with_stdio(0), cin.tie(0);
	//将g数组的数全部初始化为1,即墙;
	int t;
	cin>>t;
	while(t--){
		memset(f, 0, sizeof(f));
		cin >> n >> m;

		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				cin >> g[i][j];
		
		cin>>a>>b>>c>>d;
		bfs(a, b);
	} 
	return 0;
	
}

18276 走迷宫2

时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC;VC

Description

有一个N*M的格子迷宫,1代表该格子为墙,不能通过,0代表可以通过,另外,在迷宫中
有一些传送门,走到传送门的入口即会自动被传送到传送门的出口(一次传送算1步)。人在迷宫中可以尝试
上下左右四个方向移动。现在给定一个迷宫和所有传送门的出入口,以及起点和终点,
问最少多少步可以走出迷宫。如果不能走出迷宫输出“die”。

输入格式

该程序为多CASE,第1行为CASE的数量
每一个CASE,第1行为两个数N(行)和M(列)
然后N行每行M个数
之后是一个数W,为传送门的数量
之后每行一个传送门的入口坐标c1(行),r1(列)和出口坐标c2,r2
之后是起点坐标和终点坐标sc(行) sr(列) ec(行) er(列)

注:传送门出入口和起点坐标和终点坐标不会出现在墙的位置
所有数字不超过100

输出格式

如题

输入样例

2
4 3
011
011
110
110
1
1 0 2 2
0 0 3 2
2 2
01
10
0
0 0 1 1

输出样例

3
die

#include <iostream>
#include <cmath>
#include<algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 115;
typedef pair<int, int> pii;
int n, m, f[N][N], a, b, c, d, pos[N][4],st[N][N];
//f[N][N]存距离
char g[N][N];//存地图
int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 }, x, y, w,mark;
//三个点:
void bfs(int a, int b) {
	queue<pii>q;
	q.push({ a,b });
	while (q.size()) {
		pii start = q.front();//先进先出 
		q.pop();
		int sf = start.first, sc = start.second;
		if (sf == c && sc == d){
			cout << f[c][d] << endl;
			return;
		}

		//传送门:第五个方向
		for (int j = 0; j < w; j++) {
			if (sf == pos[j][0] && sc == pos[j][1] ) {
				
				x = pos[j][2];
				y = pos[j][3];
				g[x][y] = '1';

				f[x][y] = f[sf][sc] + 1;
				q.push({ x,y });
				mark = 1;
				break;
			}
		}
		if (mark) {
			mark = 0;
			continue;
		}
		//上下左右四个方向
		for (int i = 0; i < 4; i++) {		
				x = sf + dx[i], y = sc + dy[i];
				if(x >= 0 && x < n && y >= 0 && y < m && g[x][y] == '0' ) {
					g[x][y] = '1';
					f[x][y] = f[sf][sc] + 1;
					q.push({ x,y });	
				}
		}
	}

	cout << "die" << endl;
}
int main() {
	int t;
	cin >> t;
	while (t--) {
		cin >> n >> m;
		for (int i = 0; i < n; i++) 
			for (int j = 0; j < m; j++) 
				cin >> g[i][j];
		memset(f, 0, sizeof(f));//清空f数组 
		cin >> w;
		//传送门的入口与出口
		for (int i = 0; i < w; i++)cin >> pos[i][0] >> pos[i][1] >> pos[i][2] >> pos[i][3];
		cin >> a >> b >> c >> d;//起点与终点
		bfs(a, b);
	}
	return 0;
}

18105 银行的叫号顺序

时间限制:8000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC;VC

Description

银行的叫号过程是一个优先队列的典型应用,假设,银行有4类客户,分别用优先级1,2,3,4表示,级别越高
则更优先得到服务,例如,当前有三个人排队,两个1级客户,一个3级客户,则银行叫号时,3级客户将先得到服务
,即使另两个1级有客户比他先到。当多个同级的客户将获得服务时,由先到的客户先得到服务。

假设,银行只有一个服务窗口,一次只能服务一个客户,假设该窗口每5分钟服务一个客户,即叫号的时刻分别
为0分钟、5分钟、10分钟、…如果在叫号的时侯,没有客户,银行职员会去喝杯咖啡或上个洗手间,5分钟后
再继续叫号。

银行给出一系列客户到来的记录,每条记录包括“客户到来的时”,“客户等级”,“客户姓名”(由一个单词构成),请输
出银行服务的客户的顺序。

输入格式

第一数字是客户的数量n(n<=100000)
此后,每一行是一个客户来访信息,包括3个数字,到来的时刻(分钟整点,最大10的8次方)、等级、姓名(最多20个字母)
(已经按到来时刻排序)

输出格式

优先队列
按服务的先后顺序输出客户的姓名

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

int main()
{
    // 初始化变量
	int n, time, vip, t = 99999, rt = -5; // n代表输入的次数,time代表到达时间,vip代表是否是VIP,t代表优先级计数器,rt代表当前时间
	string name; // 顾客名字
	priority_queue<pair<int, string>> q; // 优先队列,存储<pair<优先级, 顾客名字>>

    // 输入顾客数量
	cin >> n;

    // 循环处理每个顾客
	while (n--) {
        // 输入顾客信息
		cin >> time >> vip >> name;

        // 处理等待队列中已到达的顾客
		while (time > rt) {
			if (!q.empty()) {
				cout << q.top().second << endl; // 输出队首顾客的名字
				q.pop(); // 弹出队首顾客
			}
			rt += 5; // 更新当前时间
		}

        // 将当前顾客加入等待队列
		q.push({ vip * 100000 + t, name }); // 根据VIP状态和优先级计数器构建优先级
		t--; // 优先级计数器递减
	}

    // 处理剩余等待队列中的顾客
	while (!q.empty()) {
		cout << q.top().second << endl; // 输出队首顾客的名字
		q.pop(); // 弹出队首顾客
	}
	return 0;
}

18216 银行服务

时间限制:8000MS 代码长度限制:10KB
提交次数:100 通过次数:8

题型: 编程题 语言: G++;GCC;VC

Description

银行通过叫号来决定服务用户的顺序,假设,银行有4类客户,分别用优先级1,2,3,4表示,级别越高
则更优先得到服务,例如,当前有三个人排队,两个1级客户,一个3级客户,则银行叫号时,3级客户将先得到服务
,即使另两个1级的客户比他先到。当多个同级的客户将获得服务时,由先到的客户先得到服务。

假设,银行只有一个服务窗口,一次只能服务一个客户,假设该窗口每5分钟服务一个客户,即叫号的时刻分别
为0分钟、5分钟、10分钟、…如果在叫号的时侯,没有客户,银行职员会去喝杯咖啡或上个洗手间,5分钟后
再继续叫号。

有一种情况,银行工作到一定时间是要下班的,所以到一定时间,如果后面还有客户,将不再提供服务。

银行给出一系列客户到来的记录,每条记录包括“客户到来的时间”,“客户等级”,“客户姓名”(由一个单词构成),请输
出该银行这一轮服务的客户的顺序。

输入格式

第一行两个数字,第一数字是客户的数量n(n<=100000),第二个数字是银行关门的时间,到这个时间,即关门,该点及之后,
不再叫号,但之前已经叫号的客户会继续服务到完结。
此后,每一行是一个客户来访信息,包括3个数字,到来的时刻(分钟整点,最大10的8次方)、等级、姓名(最多20个字母)
(已经按到来时刻排序,注意:同一时刻可能会同时到来多个客户,这时若为同等级的,数据出现得早的稍早得到服务)

输出格式

按服务的先后顺序输出客户的姓名

输入样例

4 12
0 1 John
3 1 Smith
3 1 Tom
4 2 Flod

输出样例

John
Flod
Smith

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int n, t, vip, curt = -5,k=99999,endt;
priority_queue<pair<int, string>>q;
string name;
int main()
{
	cin >> n >> endt;
	while (n--) {
		cin >> t >> vip >> name;
		while (t > curt) {
			if (q.size()) {
				cout << q.top().second << endl;
				q.pop();
			}
			curt += 5;
		}
		q.push({ vip * 100000 + k--,name });
	}
	while (q.size()) {
		if (curt >= endt)break;
		curt += 5;
		cout << q.top().second << endl;
		q.pop();
	}
	return 0;
}

18118 勇者斗恶龙

时间限制:800MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC;VC

Description

有n个头的恶龙,你希望雇一些骑士把它杀死(即砍掉所有头)。村里有m个骑士可以雇佣,一个能力值为x的骑士可以砍掉恶龙
一个直径不超过x的头,且需要支付x个金币。如何雇佣骑士才能砍掉恶龙的所有头,且需要支付的金币最少?注意,一个骑士只
能砍一个头(且不能被雇佣两次)

输入格式

多组数据,每组数据的第一行为正整数n和m(1<=n,m<=200000);以下n行每行为一个整数,即恶龙每个头的直径;以下m行每行为
一个整数,即每个骑士的能力。输入结束标志n=m=0;

输出格式

输出格式:每组数据,输出最少花费,无解输出"Loowater is doomed!"

输入样例

2 3
5
4
7
8
4
2 1
5
5
10
0 0

输出样例

11
Loowater is doomed!

双指针算法
i,j维护一段区间

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 2000010;
int n, m;
int a[N], b[N];
int main()
{
	while (cin >> n >> m && n && m) {
		for (int i = 0; i < n; i++)cin >> a[i];
		for (int i = 0; i < m; i++)cin >> b[i];
		sort(a, a + n);
		sort(b, b + m);
		int i, j,ans=0;
		for (i = 0, j = 0;j<m&&i<n;j++ ) {
			if (a[i] <= b[j]) {
				i++;
				ans += b[j];
			}
		}
		if (i == n)cout << ans<<endl;
		else cout<<"Loowater is doomed!"<<endl;
	}
	return 0;
}

18107 校赛排名

时间限制:4000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC;VC

Description

校赛结束了,每一个参赛选手由3个数据项构成(通过题数,用时分钟数,姓名),排名按照通过题数排序
通过题数多的排前,同题数的,罚时少的排前。如果题数相同,罚时也相同,而按数据读取的先后排。
给你N个参赛选手的数据,按排序先后,输出姓名

输入格式

第一个数为N,(N<=500000)
此后,每行一个参赛选手的数据,通过题数,用时分钟数,姓名,前两者为整型数,姓名为字符串(不多于20个字符)

输出格式

姓名排名

输入样例

4
3 5 Jon
5 100 Smith
3 5 Tom
6 95 Hel

输出样例

Hel
Smith
Jon
Tom

提示

由于有500000个数据,输入和输出务必使用scanf和printf

sort的用法

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 500010;
struct data {
	int num, time,id;
	string name;
}peo[N];
int n;
bool cmp(struct data a, struct data b) {
	if (a.num != b.num)return a.num > b.num;
	else {
		if (a.time != b.time)return a.time < b.time;
		else {
			return a.id < b.id;
		}
	}
}
int main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> peo[i].num >> peo[i].time >> peo[i].name;
		peo[i].id = i;
	}
	sort(peo, peo + n,cmp);
	for (int i = 0; i < n; i++)cout << peo[i].name << endl;
	return 0;
}

18005 它不是丑数

Description

“丑数”是指除了质因子2,3,5,不含其它质因子的正整数,例如由小到大前10个“丑数”为
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, …
非“丑数”的前10个数为
7, 11, 13, 14, 17, 19, 21, 22, 23, 26, …
现要求编写一个程序,输出指定第几位的非“丑数”。

输入格式
第一行为正整数T(T<=10000), 表示case的数目。
此后T行,每行一个正整数 n (n <= 100000000).

输出格式
每一个n,输出第n个非“丑数”
描述:先求出丑数数组,非丑数就是在两个丑数之间,因此用count计算两个丑数之间非丑数的数量并进行累加,直到大于m,然后再减去上一次非丑数的数量,再u[i]+m-count。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <math.h>
using namespace std;
long long u[3000]={1};
void Ugly()
{
    int i=1;
    long long a=0,b=0,c=0;
    long long t2=0,t3=0,t5=0;
    while(i<1200)
    {
        t2=u[a]*2;
        t3=u[b]*3;
        t5=u[c]*5;
        u[i]=min(t2,min(t3,t5));
        if(t2==u[i]) a++;
        if(t3==u[i]) b++;
        if(t5==u[i]) c++;
        i++;
    }
}
 
int main()
{
    int n,i=0;
    cin>>n;
    Ugly();
    while(n--)
    {
        int m=0;
        cin>>m;
        int count=0;
        while(count<m)
        {
            count =count+(u[i+1]-u[i]-1);
            //cout<<count;
            i++;
        }
        i--;
        count=count-(u[i+1]-u[i]-1);
        cout<<u[i]+m-count<<endl;
        i=0;
    }
    return 0;
}
  • 10
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值