UPC Contest2824 - 2021个人训练赛第13场

问题 A: Rotate

时间限制: 1 Sec  内存限制: 128 MB

题目描述

Given is a string S of length 3.
Move the first character of S to the end of S and print the resulting string S′.

Constraints
S is a string of length 3 consisting of lowercase English letters.

输入

Input is given from Standard Input in the following format:
S

输出

Print S′.

样例输入

【样例1】
abc
【样例2】
aab

样例输出

【样例1】
bca
【样例2】
aba

提示

样例1解释
Moving the first character a of the string abc results in bca.

 

将第一个字符转移到末尾。

 

#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
#include<string>
#include<stack>
#include<map>
#include<list>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<functional>
#include<limits.h>
#include<float.h>
#define pi 3.14159265358979323846264338327950288419716939937510582097494
using namespace std;
#define _for(i, a, b) for(unsigned int i=(a);i<(b);++i)
#define _rep(i, a, b) for(unsigned int i=(a);i<=(b);++i)
#define _re_for(i, a, b)	for(unsigned int i=(a);i>(b);--i)
#define _re_rep(i, a, b)	for(unsigned int i=(a);i>=(b);--i)
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
const int INF1 = 0x3f3f3f3f;
const int INF0 = 0xc0c0c0c0;

deque<char >s;

int main() {
	char c;
	while (cin >> c) s.push_back(c);
	c = s.front();
	s.pop_front();
	s.push_back(c);
	for (auto &it : s)	cout << it;
	return 0;
}

 

 

问题 B: Visibility

时间限制: 1 Sec  内存限制: 128 MB

题目描述

We have a grid of H horizontal rows and W vertical columns, where some of the squares contain obstacles.
Let (i,j) denote the square at the i-th row from the top and j-th column from the left.You are given H  strings S1,S2,S3,…,SH. The j-th character of Si describes the square (i,j); # means the square contains an obstacle, and . means it does not.
We say a square is visible from another when it is on the same row or the same column, and there is no obstacle between them (including themselves).
Print the number of squares visible from the square (X,Y) (including (X,Y) itself).

Constraints
1≤H≤100
1≤W≤100
1≤X≤H
1≤Y≤W
Si is a string of length W consisting of . and #.
The square (X,Y) does not contain an obstacle.

 

输入

Input is given from Standard Input in the following format:
H W X Y
S1
S2
S3

SH

 

输出

Print the answer.

样例输入

【样例1】
4 4 2 2
##..
...#
#.#.
.#.#
【样例2】
3 5 1 4
#....
#####
....#
【样例3】
5 5 4 2
.#..#
#.###
##...
#..#.
#.###

样例输出

【样例1】
4
【样例2】
4
【样例3】
3

提示

样例1解释
The squares visible from the square (2,2) are:
(2,1)
(2,2)
(2,3)
(3,2)
样例2解释
Even if two squares are on the same row or the same column, they are not visible from each other when there are obstacles between them.

 

从给定位置(x,y)上下左右四个方向遍历,统计从该位置开始有几连续的'.'。

PS : 非BFS。

 

#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
#include<string>
#include<stack>
#include<map>
#include<list>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<functional>
#include<limits.h>
#include<float.h>
#define pi 3.14159265358979323846264338327950288419716939937510582097494
using namespace std;
#define _for(i, a, b) for(unsigned int i=(a);i<(b);++i)
#define _rep(i, a, b) for(unsigned int i=(a);i<=(b);++i)
#define _re_for(i, a, b)	for(unsigned int i=(a);i>(b);--i)
#define _re_rep(i, a, b)	for(unsigned int i=(a);i>=(b);--i)
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
const int INF1 = 0x3f3f3f3f;
const int INF0 = 0xc0c0c0c0;

// INT_MAX       INT_MIN
// DBL_MAX       DBL_MIN
ll read() {
	ll x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-')      f = -1;
		c = getchar();
	}
	while (isdigit(c))   x = x * 10 + (c - 48), c = getchar();
	return x * f;
}

char mp[110][110];
int ans, h, w, x, y;

int main() {
	cin >> h >> w >> x >> y;
	_rep(i, 1, h)	_rep(j, 1, w)	cin >> mp[i][j];
	for (int i = x - 1, j = y; i >= 1 && mp[i][j] == '.'; i--)	ans ++;

	for (int i = x + 1, j = y; i <= h && mp[i][j] == '.'; i++)	ans ++;

	for (int i = x, j = y - 1; j >= 1 && mp[i][j] == '.'; j--)	ans ++;

	for (int i = x, j = y + 1; i <= w && mp[i][j] == '.'; j++)	ans ++;

	mp[x][y] == '.' ? cout << ans + 1 : cout << ans ;
	return 0;
}

 

 

问题 G: 欢迎

时间限制: 1 Sec  内存限制: 128 MB

题目描述

欢迎参加 2020 年常州市“程序设计小能手”比赛!小 X 想为你献上一张贺卡,不过...你得自己打印出来。 
贺卡由三行组成。其中第二行为”*Welcome,ContestantNo.A!*”,其中 A 是选手的编号。第一行和第三行相同,是和第二行字符数量相同的”*”组成。你可以通过样例来理解。 

输入

输入数据只有一行,包含一个正整数 A(A<=109),表示选手的编号。

输出

输出三行,表示贺卡。 

样例输入

【样例1】
1 
【样例2】
233 

样例输出

【样例1】
************************* 
*Welcome,ContestantNo.1!* 
************************* 
【样例2】
*************************** 
*Welcome,ContestantNo.233!* 
***************************

三行输出长度由第二行输出串的长度决定:输入数字长度加上"*Welcome,ContestantNo.!*"的长度。

 

#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
#include<string>
#include<stack>
#include<map>
#include<list>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<functional>
#include<limits.h>
#include<float.h>
#define pi 3.14159265358979323846264338327950288419716939937510582097494
using namespace std;
#define _for(i, a, b) for(unsigned int i=(a);i<(b);++i)
#define _rep(i, a, b) for(unsigned int i=(a);i<=(b);++i)
#define _re_for(i, a, b)	for(unsigned int i=(a);i>(b);--i)
#define _re_rep(i, a, b)	for(unsigned int i=(a);i>=(b);--i)
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
const int INF1 = 0x3f3f3f3f;
const int INF0 = 0xc0c0c0c0;

// INT_MAX       INT_MIN
// DBL_MAX       DBL_MIN
ll read() {
	ll x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-')      f = -1;
		c = getchar();
	}
	while (isdigit(c))   x = x * 10 + (c - 48), c = getchar();
	return x * f;
}

string smid = "*Welcome,ContestantNo.";

int main() {
	ll n;
	n = read();
	string s;
	s = to_string(n);
	smid += s;
	smid += "!*";
	_rep(i, 1, smid.size())	cout << '*';
	cout << endl;
	cout << smid << endl;
	_rep(i, 1, smid.size())	cout << '*';
	return 0;
}

 

 

问题 H: 比赛

时间限制: 1 Sec  内存限制: 128 MB

题目描述

小 X 参加了一场作文比赛的初赛。算上小 X,他的学校一共有 n 个人参加了这场比赛。一个礼拜后,小 X 兴奋地打开比赛官网,发现一等奖、二等奖、三等奖的分数线和所有人的得分都已经公布了,但没有提到获得什么奖项才能进入复赛。小 X 想问问你,如果要获得了 A 等奖才能进入复赛的话,他的学校有多少人能进入复赛呢? 
假设 A 等奖的分数线是 x,一个人的分数是 y,那么如果 y 大于等于 x,这个人就获得了 A 等奖。 

输入

输入数据共有四行。 
第一行一个正整数 n,表示小 X 的学校一共有 n 个人参加了比赛。 
第二行 n 个正整数,表示小 X 的学校中所有人的得分。 
第三行三个正整数 L3,L2,L1,分别表示三等奖、二等奖、一等奖的分数线。 
第四行一个正整数 A,表示要获得了 A 等奖才能进入复赛。 

输出

输出一行包含一个整数,表示有多少人进入复赛。 

样例输入

4 
99 101 200 300 
100 200 300 
2 

样例输出

2

提示

样例解释 
第一个人 99 分,没有奖项 
第二个人 101 分,获得了三等奖 
第三个人 200 分,获得了三等奖、二等奖 
第四个人 300 分,获得了三等奖、二等奖、一等奖 
一共有 2 个人获得了二等奖,所以有 2 个人进入复赛 
数据范围 
本题共有 10 个测试点,每个测试点 8 分 
对于全部数据:所有人的得分<=1000,L3<=L2<=L1<=1000,A 是{1,2,3}中的一个 
对于测试点 1-2 :n=1 对于测试点 3-6 :n<=10 
对于测试点 7-10:n<=10000 

 

统计一下有几人过线。

 

#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
#include<string>
#include<stack>
#include<map>
#include<list>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<functional>
#include<limits.h>
#include<float.h>
#define pi 3.14159265358979323846264338327950288419716939937510582097494
using namespace std;
#define _for(i, a, b) for(unsigned int i=(a);i<(b);++i)
#define _rep(i, a, b) for(unsigned int i=(a);i<=(b);++i)
#define _re_for(i, a, b)	for(unsigned int i=(a);i>(b);--i)
#define _re_rep(i, a, b)	for(unsigned int i=(a);i>=(b);--i)
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
const int INF1 = 0x3f3f3f3f;
const int INF0 = 0xc0c0c0c0;

// INT_MAX       INT_MIN
// DBL_MAX       DBL_MIN
ll read() {
	ll x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-')      f = -1;
		c = getchar();
	}
	while (isdigit(c))   x = x * 10 + (c - 48), c = getchar();
	return x * f;
}

ll n, ans, flag;
ll lev[4], record[10010];

int main() {
	n = read();
	_rep(i, 1, n)	record[i] = read();
	lev[3] = read();
	lev[2] = read();
	lev[1] = read();
	flag = read();
	_rep(i, 1, n)	if (record[i] >= lev[flag])	ans++;
	cout << ans;
	return 0;
}

 

 

问题 J: 重点单词

时间限制: 1 Sec  内存限制: 128 MB

题目描述

回家后,小 X 望着自己打瞌睡时写的英语笔记陷入了迷茫。由于太困了,他会时不时地把一个字母多写几次:比如可能把“she”写成“shhe”,也可能写成“ssshee”。 
但他依稀记得这堂课只讲了一个重点单词。为了找到这个单词,他想先把每个单词中连续重复的字母压缩起来:把“coool”压缩为“col”,把“aabbaa”压缩为“aba”。接下来找到压缩后出现次数最多的单词,这样就能找到重点单词了。 
由于工作量太大,小 X 希望你帮助他找到重点单词。他向你保证压缩后的单词出现次数最多的一定唯一。 

输入

第一行一个整数 n 表示笔记上共写了 n 个单词。 
接下来 n 行,每行一个字符串,表示一个单词。

输出

输出数据只有一行,包含一个字符串,表示压缩后出现次数最多的单词。 

样例输入

3 
qaaqqq 
qwwwwq 
qqqqaq

样例输出

qaq

提示

样例解释 
“qaaqqq”压缩成“qaq” 
“qwwwwq”压缩成“qwq” 
“qqqqaq”压缩成“qaq” “qaq”出现了两次,“qwq”出现了一次所以“qaq”出现次数最多 
数据范围 
本题共有 10 个测试点,每个测试点 10 分 
对于全部数据:单词长度<=50 
对于测试点 1   :n=1,单词长度为 1 
对于测试点 2-3 :n<=10000,单词长度为 1 
对于测试点 4-6 :n=1 
对于测试点 7-8 :n<=10 
对于测试点 9-10:n<=10000 

 

单词压缩规则:连续的相同字符缩减为一个,每次判断读入的字符是否与容器尾存放的字符是否相同,不同则放入。

利用map存储。

这里只需查找,用unordered_map效率更高。

 

#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
#include<string>
#include<stack>
#include<map>
#include<list>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<functional>
#include<limits.h>
#include<float.h>
#define pi 3.14159265358979323846264338327950288419716939937510582097494
using namespace std;
#define _for(i, a, b) for(unsigned int i=(a);i<(b);++i)
#define _rep(i, a, b) for(unsigned int i=(a);i<=(b);++i)
#define _re_for(i, a, b)	for(unsigned int i=(a);i>(b);--i)
#define _re_rep(i, a, b)	for(unsigned int i=(a);i>=(b);--i)
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
const int INF1 = 0x3f3f3f3f;
const int INF0 = 0xc0c0c0c0;

// INT_MAX       INT_MIN
// DBL_MAX       DBL_MIN
ll read() {
	ll x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-')      f = -1;
		c = getchar();
	}
	while (isdigit(c))   x = x * 10 + (c - 48), c = getchar();
	return x * f;
}

ll n;
unordered_map<string, int>mp;
string ans;
ll cnt;

int main() {
	n = read();
	while (n--) {
		string s;
		cin >> s;
		string temp;
		_for(i, 0, s.size())	if (s[i] != temp.back())	temp.push_back(s[i]);
		mp[temp]++;
		if (cnt < mp[temp]) {
			cnt = mp[temp];
			ans = temp;
		}
	}
	cout << ans;
	return 0;
}

 

 

问题 K: 勇士斗恶龙

时间限制: 1 Sec  内存限制: 128 MB

题目描述

小 X 穿越到了异世界,国王命令他招揽勇士,杀死恶龙,救回公主。 
异世界是高度数据化的。恶龙有一个攻击力 ATK,一个生命值 HP。类似的,每个勇士也有一个攻击力 Ai,一个生命值 Hi。 
战斗是回合制的,并且每次只能由一个勇士和恶龙单挑。战斗中,每个回合恶龙的生命值会减去这个勇士的攻击力,这个勇士的生命值会减去恶龙的攻击力。
如果回合结束的时候恶龙的生命值小于等于 0,那么恶龙就被杀死了;如果这个勇士的生命值小于等于 0,那么这个勇士就被击败了,需要换上另一个勇士继续战斗。当然,如果恶龙还没有被杀死,勇士却全部被击败了,那么这场战役就彻底失败了。 
不过聪明的小 X 安排了一个特殊的战术:在一名勇士被击败后立刻让另一名勇士发起攻击,这样恶龙在勇士们的车轮战术下疲于招架,受到第二个勇士的伤害变为两倍,受到第三个勇士的伤害变为三倍……以此类推。 
现在一共有 n 名勇士报名,小 X 想问问你,如果合理安排勇士出战的顺序,最少要招揽多少名勇士才能杀死恶龙? 

输入

第一行为一个正整数 n,表示一共有 n 名勇士报名。 
第二行两个正整数 ATK 和 HP 表示恶龙的攻击力和生命值。 
接下来共有 n 行,每行两个正整数 Ai 和 Hi 表示这名勇士的攻击力和生命值。 

输出

输出一个整数,表示最少要招揽多少名勇士才能杀死恶龙。 
如果不可能杀死恶龙,输出”Fail”。 

样例输入

2 
1 9
2 2 
1 1

样例输出

2

提示

样例解释 
两名勇士都招揽。先派出 2 号勇士 
第一回合,恶龙生命值变为 8,勇士生命值变为 0。勇士被击败 
紧接着派出 1 号勇士 
第二回合,恶龙生命值变为 4(两倍伤害),勇士生命值变为 1 
第三回合,恶龙生命值变为 0,勇士生命值变为 0。恶龙被杀死 
勇士虽然也被击败了,但恶龙已经死了,所以还是胜利了! 
数据范围 
本题共有 10 个测试点,每个测试点 15 分 
对于测试点 1-4  :n<=5,ATK,Hi,Ai<=10,HP<=100 
对于测试点 5-7  :n<=1000,ATK,Hi,Ai<=1000,HP<=10^9 
对于测试点 8-10 :n<=10^5,ATK,Hi,Ai<=10^6,HP<=10^18 

 

一直精于贪心(偷鸡)算法的我愣是一开始用性价比和背包的思想考虑这道题,总是有数据不过,最后改了一下性价比的算法,加上前缀和和贪心过了。

 

贪心思路:

对于每个勇者(炮灰),其能造成的伤害(绝对伤害,在某次PK中不计倍数的情况下,所能造成的总伤害),越晚攻击龙,所获得的伤害倍数越大,即造成的伤害越高。对此进行升序排序。

以饱和攻击策略进行攻击:每次拿造成绝对伤害的最大的ans个勇者去送(ans,从1遍历到n),如果ans个勇者造成的攻击(计伤害倍数)之和大于龙的生命值,则答案已得。

 

前缀和优化:

每次求伤害和是一个区间和,用前缀和可大大缩减时间。

用sum保存当前不计伤害倍数ans个勇者的绝对攻击和,last保存本次ans个和与ans-1个和。

ans = N1 

temp = N1 + N2

now = ans + temp = 2N1 + 1N2

以此类推,得到SUM(带伤害倍数的总伤害) = ansN1 + (ans - 1)N2 + (ans - 2)N3 + ~ + 1Nans

 

#include<iostream>
#include<bits/stdc++.h>
#include<algorithm>
#include<string>
#include<stack>
#include<map>
#include<list>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<functional>
#include<limits.h>
#include<float.h>
#define pi 3.14159265358979323846264338327950288419716939937510582097494
using namespace std;
#define _for(i, a, b) for(unsigned int i=(a);i<(b);++i)
#define _rep(i, a, b) for(unsigned int i=(a);i<=(b);++i)
#define _re_for(i, a, b)	for(unsigned int i=(a);i>(b);--i)
#define _re_rep(i, a, b)	for(unsigned int i=(a);i>=(b);--i)
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
const int INF1 = 0x3f3f3f3f;
const int INF0 = 0xc0c0c0c0;

// INT_MAX       INT_MIN
// DBL_MAX       DBL_MIN
ll read() {
	ll x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-')      f = -1;
		c = getchar();
	}
	while (isdigit(c))   x = x * 10 + (c - 48), c = getchar();
	return x * f;
}

ll n;
ll dlglife, dlgatc, a, b;
vector<ll> vec;

int main() {
	n = read();
	dlgatc = read();
	dlglife = read();
	_rep(i, 1, n) {
		a = read();
		b = read();
		vec.push_back(ceil((double)(b) / (double)(dlgatc)) * a);
	}
	sort(vec.begin(), vec.end());
	ll qz[n + 1] = {0};
	qz[1] = vec[0];
	_rep(i, 2, n)	qz[i] = qz[i - 1] + vec[i - 1];
	ll last = 0;
	_rep(i, 1, n) {
		ll sum = qz[n] - qz[n - i];
		last += sum;
		if (last >= dlglife) {
			cout << i;
			return 0;
		}
	}
	cout << "Fail";
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值