给定一个字符串来代表一个员工的考勤纪录,这个纪录仅包含以下两个字符:
'A' : Absent
,缺勤
'P' : Present
,到场
如果一个员工的考勤纪录中不超过两个'A'
(缺勤),那么这个员工会被奖赏。
如果你作为一个员工,想在连续N
天的考勤周期中获得奖赏,请问有多少种考勤的组合能够满足要求
输入描述:
考勤周期的天数N
(正整数)
输出描述:
这N
天里能获得奖赏的考勤组合数
样例:
3 >--------------------------------------------------< 7
C n 2 + C n 1 + C n 0 C_n^2+C_n^1+C_n^0 Cn2+Cn1+Cn0。
#include
int main()
{
for (int n; std::cin >> n; std::cout << n * (n - 1) / 2 + n + 1 << std::endl) {}
return 0;
}
一条包含字母 A-Z
的消息通过以下方式进行了编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
输入描述:
一串编码过的数字,比如12
输出描述:
解码方法的总数
样例:
12 >--------------------------------------------------< 2
基本动态规划,注意数字为0, 0[0-9], 2[7-9], [3-9][0-9]
是不合法的。
#include
int main()
{
for (std::string str; std::cin >> str; ) {
int dp[2];
if (str.size() >= 1)
dp[0] = str.front() != '0';
if (str.size() >= 2)
dp[1] = (str.front() != '0' && (str[0] == '1' || (str[0] == '2' && str[1] <= '6'))) + (str[1] != '0' ? dp[0] : 0);
for (unsigned i = 2; i < str.size(); ++i)
dp[i & 1] = (str[i] != '0' ? dp[(i - 1) & 1] : 0) +
(str[i - 1] != '0' && (str[i - 1] == '1' || (str[i - 1] == '2' && str[i] <= '6')) ? dp[(i - 2) & 1] : 0);
std::cout << dp[(str.size() - 1) & 1] << std::endl;
}
return 0;
}
公司组织团建活动,到某漂流圣地漂流,现有如下情况:
员工各自体重不一,第 i
个人的体重为 people[i]
,每艘漂流船可以承载的最大重量为 limit
。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit
。
为节省开支,麻烦帮忙计算出载到每一个人所需的最小船只数(保证每个人都能被船载)。
输入描述:
第一行输入参与漂流的人员对应的体重数组
第二行输入漂流船承载的最大重量
输出描述:
所需最小船只数
样例:
1 2 3 >--------------------------------------------------< 1
贪心,尽可能让每条船满负荷。
#include
int main()
{
std::string arrString;
std::getline(std::cin, arrString);
std::stringstream sin(arrString);
std::multiset<int> arr;
for (int x; sin >> x; arr.emplace(x)) {}
int limit, ans = 0;
std::cin >> limit;
for (auto it = std::begin(arr); it != std::end(arr); ) {
auto pos = arr.find(limit - *it);
if (pos != std::end(arr) && it != pos) {
arr.erase(pos);
it = arr.erase(it);
++ans;
} else {
++it;
}
}
for (auto it = std::begin(arr); it != std::end(arr); ) {
auto pos = arr.upper_bound(limit - *it);
if (pos != std::begin(arr) && pos != ++std::begin(arr) && *std::prev(pos) < limit - *it) {
arr.erase(--pos);
it = arr.erase(it);
++ans;
} else {
it = arr.erase(it);
++ans;
}
}
std::cout << ans << std::endl;
return 0;
}
我们有很多区域,每个区域都是从a
到b
的闭区间,现在我们要从每个区间中挑选至少2
个数,那么最少挑选多少个?
输入描述:
第一行是N
(N
<10000
),表示有N
个区间,之间可以重复
然后每一行是ai,bi
,持续N
行,表示现在区间。均小于100000
输出描述:
输出一个数,代表最少选取数量。
样例:
4 4 7 2 4 0 2 3 6 >--------------------------------------------------< 4
这个题是典型的区间选点的变形。原题是POJ - 1716。
区间选点问题的链接:POJ - 1328,要求每个区间至少一个点。
而这个题要求每个区间至少两个点。
一样的啊,贪心,按右端点排序(左端点一样可以),如果每个区间至少一个点,那么这个点一定是在右端点,这样子可以让后续的区间更容易覆盖到这个点,从而减少选点的数量;同理,如果每个区间至少两个点,那个这个两个点一定也在右端点和右端点前一个点,原因是一样的。
这个题还可以扩展成每个区间至少三个点,四个点…
终极扩展是POJ - 1201。每个区间至少c[i]
个点。一样可以贪心搞,只不过要用树状数组维护一下而已。
不过这类题还可以用差分约束系统来搞,这里就不细说了。有兴趣自己可以学一下。
#include
int main()
{
for (int n; std::cin >> n; ) {
typedef std::pair<int, int> Line;
std::vector<Line> lines;
for (int i = 0, x, y; i < n; std::cin >> x >> y, lines.emplace_back(x, y), ++i) {}
std::sort(std::begin(lines), std::end(lines), [] (const Line & A, const Line & B) {
return A.second < B.second;
});
std::vector<int> points {lines[0].second - 1, lines[0].second};
for (int i = 1; i < n; ++i) {
if (lines[i].first <= points[points.size() - 2]) {
nullptr;
} else if (lines[i].first <= points.back()) {
if (lines[i].second != points.back()) points.emplace_back(lines[i].second);
} else {
points.emplace_back(lines[i].second - 1);
points.emplace_back(lines[i].second);
}
}
std::cout << points.size() << std::endl;
}
return 0;
}
考虑你从家出发步行去往一处目的地,该目的地恰好离你整数单位步长(大于等于1
)。你只能朝向该目的地或者背向该目的地行走,而你行走的必须为单位步长的整数倍,且要求你第N
次行走必须走N
步。
请就给出目的地离你距离,判断你是否可以在有限步内到达该目的地。如果可以到达的话,请计算到达目的地的最短总步数(不能到达则输出-1
)。
输入描述:
1个整数:目的地离你距离T
输出描述:
1个整数:最短总步数(进行了多少次行走)
样例:
2 >--------------------------------------------------< 3
暴力 B F S BFS BFS,注意,这个题不可能出现-1
这种情况(左边走一次,右边走一次,始终可以前进一);
还要注意,这个题不能保存走过的点,因为第一次走过的点,再次走也许就是最短路径。
#include
int main()
{
for (int n; std::cin >> n; ) {
std::queue< std::pair<int, int> > que;
int ans = -1;
que.emplace(0, 0);
while (true) {
std::pair<int, int> now = que.front();
que.pop();
if (now.first == n) {
ans = now.second;
break;
}
que.emplace(now.first + now.second + 1, now.second + 1);
que.emplace(now.first - now.second - 1, now.second + 1);
}
std::cout << ans << std::endl;
}
return 0;
}