赞
踩
题意:
给四个整数
p
,
a
,
b
,
c
p,a,b,c
p,a,b,c。其中
a
,
b
,
c
a,b,c
a,b,c分别表示三个游泳者到达泳池边的时间点,比如,第一个游泳者到达泳池边的时间就是
0
,
a
,
2
a
,
3
a
,
…
0,a,2a,3a,\dots
0,a,2a,3a,…。p表示的是一个人来到泳池边的时间点,问这个人在泳池边要等多久才能见到第一个到达泳池边的游泳者。
题解:
直接找
a
,
b
,
c
a,b,c
a,b,c的大于等于p的最小倍数即可。注意数据范围比较大,保守起见开了
u
n
s
i
g
n
e
d
l
o
n
g
l
o
n
g
unsigned\ long\ long
unsigned long long。
具体细节见代码:
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ll; int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int t; cin >> t; while (t--) { ll p, a, b, c; cin >> p >> a >> b >> c; ll newa = (p + a - 1) / a * a; ll newb = (p + b - 1) / b * b; ll newc = (p + c - 1) / c * c; cout << min(newa, min(newb, newc)) - p << endl; } return 0; }
题意:
给了我们一个长度为n的排列p,p的第一个元素是底,最后一个元素是顶,我们每次可以从顶取出一些元素放在一个新牌组上,原来在p中当顶的元素成为新牌组中的底,按这种方式取出所有p的元素,让我们找出一个排列使得
∑
i
=
1
n
n
n
−
i
⋅
p
i
\sum_{i=1}^n n^{n-i}·p_i
∑i=1nnn−i⋅pi的值最大。
题解:
看起来比较棘手,不过我们分析题目所给的样例能够很快发现,其实就是从后往前找到当前剩余元素中最大的数的位置
i
i
i,然后把从
i
i
i到结尾的所有元素取出放入新牌组即可。每次按这种方式取,直到取完。
具体实现见代码:
#include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 10; int p[MAXN]; int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int t; cin >> t; while (t--) { int n; int maxx = -1, id = 0; set<int> vis; vector<int> ans; cin >> n; for (int i = 0; i < n; i++) { cin >> p[i]; if (p[i] > maxx) { maxx = p[i]; id = i; } } for (int i = n - 1; i >= 0; i--) { ans.emplace_back(p[i]); // 从顶依次加入元素 vis.insert(p[i]); // 判断元素是否被取过 if (p[i] == maxx) { // 如果当前元素是最大值,倒序输出 int len = ans.size(); for (int j = len - 1; j >= 0; j--) { cout << ans[j] << " "; } ans.clear(); while (vis.count(maxx)) { // 找到当前剩余元素中的最大值 maxx--; } } } cout << endl; } return 0; }
题意:
给我们一个长度为n的字符串S和一个长度为m的字符串T,让我们找到一个长度为m的严格上升的序列p,使得p中元素在S串中对应的字符串正好是T串,同时定义p序列的宽度是p中元素
p
i
+
1
−
p
i
p_{i+1} - p_i
pi+1−pi的最大值,问我们这个宽度最大可以是多少?
题解:
这道题目,由于求的是相邻字符对应位置的差值的最大值,那么为了使这个差值最大,我们容易想到相邻字符一个取最左的坐标,一个取最右的坐标,因此我们可以对T串前后扫两边,从前扫,每次找到当前T串字符在S串的最左的位置坐标;从后扫,每次找到当前T串字符在S串的最右的位置坐标。最后,扫描一遍T串,找到相邻字符的坐标差值最大值。
具体细节见代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 2e5 + 10; ll nowr[MAXN], nowl[MAXN]; int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int m, n; cin >> n >> m; string s, t; cin >> s >> t; ll sleft = 0; for (int i = 0; i < m; i++) { while (s[sleft] != t[i] && sleft <= n - 1) { // 找到当前t[i]在s串中的最左坐标 sleft += 1; } nowl[i] = sleft++; } ll sright = n - 1; for (int i = m - 1; i >= 0 && sright >= 0; i--) { // 找到当前t[i]在s串中的最右坐标 while (s[sright] != t[i] && sright >= 0) { sright -= 1; } nowr[i] = sright--; } ll ans = 0; for (int i = 1; i < m; i++) { ans = max(ans, nowr[i] - nowl[i - 1]); } cout << ans << endl; return 0; }
这题FST比例就离谱。感觉大部分都是错在一些特判上。
题意:
给我们3个整数
a
,
b
,
k
a,b,k
a,b,k,让我们判断能不能构造出两个二进制数
x
x
x和
y
y
y,满足:
题解:
经过手推几个样例,能够发现当
k
>
a
+
b
−
2
k>a+b-2
k>a+b−2时不能构造这样的二进制数。不过,这样其实是不对的,当样例是0 1 0的时候,我们可以构造
x
=
1
y
=
1
x=1\ y=1
x=1 y=1这样两个二进制数,因此我们要对
b
=
1
,
k
=
0
b=1,k=0
b=1,k=0的时候进行特判。我这里一般的构造方法就是,根据
a
a
a和
k
k
k的大小关系,分别进行两种不同的构造。
当 a ≥ k a≥k a≥k时,对于 x 和 y x和y x和y,先以 b − 1 b-1 b−1个1开头。然后由于最后要有k个1,因此,在 x x x中,我以倒数第 k k k个位置作为分界线,给倒数第 k k k个位置设为1,其他位置设为0;在 y y y中,我把最后一个位置设为1,其他剩余位置设为0,这样 x − y x-y x−y就一定有k个1,且满足其他条件。
当 a < k a<k a<k时,我把 x x x的最后 a a a个位置设为0,其他位置都设为1。而 y y y中,与x不同之处就在就在 a + b − k a+b-k a+b−k这个位置,在 x x x中是1,但是在 y y y中我设置为0。
按照以上方式写出的构造程序,看起来是对的,不过,少了 a = 0 a = 0 a=0时的特判。我们发现当 a = 0 , k = 0 a=0,k=0 a=0,k=0时,其实是可以构造出全部是1的两个二进制数。
具体细节见代码:
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int a, b, k; cin >> a >> b >> k; if (b == 1) { // 特判b = 1 if (k == 0) { cout << "Yes" << endl; cout << 1; for (int i = 1; i <= a; ++i) { cout << 0; } cout << endl; cout << 1; for (int i = 1; i <= a; ++i) { cout << 0; } cout << endl; } else { cout << "No" << endl; } return 0; } if (a == 0) { // 特判a = 0 if (k == 0) { cout << "Yes" << endl; for (int i = 1; i <= b; ++i) { cout << 1; } cout << endl; for (int i = 1; i <= b; ++i) { cout << 1; } cout << endl; } else { cout << "No" << endl; } return 0; } if (k > a + b - 2) { cout << "No" << endl; } else if (a >= k) { cout << "Yes" << endl; for (int i = 1; i < b; i++) { cout << 1; } for (int i = 1; i <= a - k; i++) { cout << 0; } cout << 1; for (int i = 1; i <= k; i++) { cout << 0; } cout << endl; for (int i = 1; i < b; i++) { cout << 1; } for (int i = 1; i <= a; i++) { cout << 0; } cout << 1 << endl; } else { cout << "Yes" << endl; for (int i = 1; i < a + b - k; i++) { cout << 1; } cout << 1; for (int i = 1; i <= k - a; i++) { cout << 1; } for (int i = 1; i <= a; i++) { cout << 0; } cout << endl; for (int i = 1; i < a + b - k; i++) { cout << 1; } cout << 0; for (int i = 1; i <= k - a; i++) { cout << 1; } for (int i = 1; i < a; i++) { cout << 0; } cout << 1 << endl; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。