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;
}