赞
踩
刷了两年多的题,终于开始动手写题解了,首发献给今天的腾讯笔试。
题目当初没截图存一下,靠记忆来一发。。。
题目大致是说,给你两个整数n和m,取值范围的1~10^9,且n是(2*m)的倍数,然后有这样一个规律,数组从1开始,符号为负,每隔m个数就变一次符号。例如n取8,m取2,那么数组就是
-1 -2 3 4 -5 -6 7 8
题目要求求出这n个数的和。
数据范围那么大,一般就是找规律。这题也是简单的找规律,多写几个就可以发现,每2*m个数的和就是m*m,同时n又是(2*m)的倍数,那就很好办了。结果就是m*m*(n/2/m),化简一下也行,当时约掉一个m,直接就上了。这里要注意,因为m最大可能是10^9,又要做乘法,所以得用long long,而且要先除再乘。
#include <iostream>
#include <array>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <cstdio>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using std::cin; using std::cout;
using std::array;
using std::min; using std::max;
using std::string;
using std::set; using std::vector;
using std::queue; using std::stack;
typedef long long LL;
LL solve(LL n, LL m) {
LL ans = m*m;
ans = ans * (n/2/m);
return ans;
}
int main() {
std::ios::sync_with_stdio(false);
LL n, m;
cin >> n >> m;
cout << solve(n, m) << "\n";
return 0;
}
题目是说呢,有x首长度为a的歌,以及y首长度为b的歌,然后想要用这么多首歌看能组合成多少个长度为k的歌单,在每个歌单中,每首歌只能出现一次,且不管歌的排列顺序,也就是直接组合就得了。因为结果可能较大,输出的歌单数对1000000007取模。
数据范围: k<=1000,a ,b 小于等于10, x,y小于等于100
样例:(第一个数是k,接下来依次是a, x, b, y,输出歌单数。)
输入:5 2 3 3 3
输出:9
一开始想着dp,但是歌只能出现一次,dp感觉有点麻烦,就放弃了,改成研究一下样例,发现就是直接组合起来就行了。数据那么小,暴力一下,枚举0~x跟0~y的组合,刚好长度为k的就把两者的组合数相乘取模就好了。所以这道题实际上是考组合数取模。
一开始忘记组合数取模怎么搞,直接暴力求,因为精度一直卡60%,然后就强行在每次取组合数的时候分子分母约掉最大公约数,再取模,神奇地卡到了90%。。。。(其实做除法是不能取模的,卡就卡在这里了)笔试时没做完,现在补一下。
其实组合数画出来就是个杨辉三角:
null | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
0 | 1 | |||||
1 | 1 | 1 | ||||
2 | 1 | 2 | 1 | |||
3 | 1 | 3 | 3 | 1 | ||
4 | 1 | 4 | 6 | 4 | 1 | |
5 | 1 | 5 | 10 | 10 | 5 | 1 |
所以直接递推+取模就可以出来了。
#include <iostream>
#include <array>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <cstdio>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using std::cin; using std::cout;
using std::array;
using std::min; using std::max;
using std::string;
using std::set; using std::vector;
using std::queue; using std::stack;
typedef long long LL;
const LL MOD = 1000000007;
const int MAXN = 100+5;
LL comb[MAXN][MAXN];
void init() {
for (int i=0; i<MAXN; ++i) {
comb[i][0] = comb[i][i] = 1;
for (int j=1; j<i; ++j) {
comb[i][j] = comb[i-1][j] + comb[i-1][j-1];
comb[i][j] %= MOD;
}
}
}
int main() {
std::ios::sync_with_stdio(false);
int k;
int a, x, b, y;
init();
cin >> k;
cin >> a >> x >> b >> y;
LL ans = 0;
LL val;
for (int i=0; i<=x; ++i) {
for (int j=0; j<=y; ++j) {
if (i*a + j*b == k) {
val = (comb[x][i] * comb[y][j]) % MOD;
ans += val;
ans %= MOD;
}
}
}
cout << ans << "\n";
return 0;
}
给一个n和m,范围是1~10^5,n表示机器人的个数,m表示任务数。每个机器人和任务都有两个参数,一个是时间,一个是等级。每个机器人只能做一个任务,且任务的时间不能超过机器人的时间,任务的等级不能超过机器人的等级。每完成一个任务,都能得到收益,收益是200*任务时间+3*任务等级。现在要求最多能够完成几个任务,以及最大收益是多少。
数据范围:时间<=1000,等级<=100(应该没记错吧)
一开始呢,看到范围是10^5,想着按照出题人的习惯,大范围是数据一般都是一两个样例而已,就写了一发n^2暴力。机器人按等级、时间这个优先级正序排好,任务按收益、等级、时间这个优先级逆序排好。暴力交了上去,结果过了90%,我也是惊呆了。
之后改了一下,把暴力搜索机器人改了。因为等级的数据范围比较小,所以用multiset按机器人的等级分成多个容器,每个容器存该等级机器人的时间,最后二分查找就行了。这里不能用set,因为机器人的时间可能会有重复。(虽然我用set交了一发,也是过了90%,看来只有最后一个样例才有重复的时间。。。。)
#include <iostream>
#include <array>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <cstdio>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using std::cin; using std::cout;
using std::array;
using std::min; using std::max;
using std::string;
using std::multiset; using std::vector;
using std::queue; using std::stack;
using std::sort; using std::lower_bound;
typedef long long LL;
const int MAXN = 1e5+5;
struct Work {
int time, level;
};
Work robots[MAXN];
Work arg[MAXN];
LL money(const Work& a) {
return 200*a.time + 3*a.level;
}
bool cmp_a(const Work& a, const Work& b) {
LL ma = money(a);
LL mb = money(b);
if (ma == mb) {
if (a.level == b.level)
return a.time > b.time;
else return a.level > b.level;
} else {
return ma > mb;
}
}
bool cmp_b(const Work& a, const Work& b) {
if (a.level == b.level) return a.time < b.time;
else return a.level < b.level;
}
multiset<int> rob[105];
bool isOk(const Work& w, int n) {
for (int i=w.level; i<=100; ++i) {
auto idx = lower_bound(rob[i].begin(), rob[i].end(), w.time);
if (idx != rob[i].end()) {
rob[i].erase(idx);
return true;
}
}
return false;
}
int main() {
int n, m;
scanf("%d%d",&n, &m);
for (int i=0; i<n; ++i) {
scanf("%d%d", &robots[i].time, &robots[i].level);
rob[robots[i].level].insert(robots[i].time);
}
for (int i=0; i<m; ++i)
scanf("%d%d", &arg[i].time, &arg[i].level);
sort(robots, robots+n, cmp_b);
sort(arg, arg+m, cmp_a);
int cnt = 0;
LL val = 0;
for (int i=0; i<m; ++i) {
if (isOk(arg[i], n)) {
++cnt;
val += money(arg[i]);
}
}
cout << cnt << " " << val << "\n";
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。