每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <= 50)。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。
输出一行表示最大的乘积。
3 7 4 7 2 50
49
代码清单:
#include
#include
#include
#include
using namespace std;
const int maxn = 50 + 5;
const long long minn = -1e17;
struct DP {
long long mins;
long long maxs;
}dp[maxn][15];
int n;
int a[maxn];
int k, d;
void input() {
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
scanf("%d%d", &k, &d);
}
void solve() {
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; ++i) dp[i][1].mins = dp[i][1].maxs = a[i];
long long ans = minn;
for(int i = 1; i <= n; ++i) {
for(int ki = 2; ki <= k; ++ki) {
int j = i - d;
if(j <= 0) j = 1;
for(; j < i; ++j) {
dp[i][ki].mins = min(dp[i][ki].mins, min(dp[j][ki - 1].mins * a[i], dp[j][ki - 1].maxs * a[i]));
dp[i][ki].maxs = max(dp[i][ki].maxs, max(dp[j][ki - 1].mins * a[i], dp[j][ki - 1].maxs * a[i]));
}
}
}
for(int i = 1; i <= n; ++i) {
ans = max(ans, dp[i][k].maxs);
}
printf("%lld\n", ans);
}
int main() {
while(scanf("%d", &n) != EOF) {
input();
solve();
}
return 0;
}
每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 50),表示地牢的长和宽。接下来的 n 行,每行 m 个字符,描述地牢,地牢将至少包含两个 '.'。接下来的一行,包含两个整数 x0, y0,表示牛牛的出发位置(0 <= x0 < n, 0 <= y0 < m,左上角的坐标为 (0, 0),出发位置一定是 '.')。之后的一行包含一个整数 k(0 < k <= 50)表示牛牛合法的步长数,接下来的 k 行,每行两个整数 dx, dy 表示每次可选择移动的行和列步长(-50 <= dx, dy <= 50)
输出一行一个数字表示最坏情况下需要多少次移动可以离开地牢,如果永远无法离开,输出 -1。以下测试用例中,牛牛可以上下左右移动,在所有可通行的位置.上,地牢出口如果被设置在右下角,牛牛想离开需要移动的次数最多,为3次。
3 3 ... ... ... 0 1 4 1 0 0 1 -1 0 0 -1
3
代码清单:
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 50 + 5;
struct que {
int x, y;
int step;
que() {}
que(int _x, int _y, int _step) {
this -> x = _x;
this -> y = _y;
this -> step = _step;
}
};
int n, m;
char tmap[maxn][maxn];
int sx, sy;
int k;
int dx[maxn], dy[maxn];
void input() {
for(int i = 0; i < n; ++i) {
scanf("%s", tmap[i]);
}
scanf("%d%d", &sx, &sy);
scanf("%d", &k);
for(int i = 0; i < k; ++i) {
scanf("%d%d", &dx[i], &dy[i]);
}
}
bool check(int x, int y) {
return (x >= 0 && x < n && y >= 0 && y < m && tmap[x][y] == '.');
}
int bfs() {
queue q;
q.push(que(sx, sy, 0));
bool vis[maxn][maxn];
memset(vis, false, sizeof(vis));
vis[sx][sy] = true;
int ans = 0;
while(!q.empty()) {
que p = q.front(); q.pop();
ans = max(ans, p.step);
for(int i = 0; i < k; ++i) {
int xx = p.x + dx[i];
int yy = p.y + dy[i];
if(!vis[xx][yy] && check(xx, yy)) {
vis[xx][yy] = true;
q.push(que(xx, yy, p.step + 1));
}
}
}
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
if(tmap[i][j] == '.' && vis[i][j] == false) {
return -1;
}
}
}
return ans;
}
void solve() {
printf("%d\n", bfs());
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
input();
solve();
}
return 0;
}
每个输入包含 1 个测试用例。每个测试用例的第 i 行,表示完成第 i 件料理需要哪些材料,各个材料用空格隔开,输入只包含大写英文字母和空格,输入文件不超过 50 行,每一行不超过 50 个字符。
输出一行一个数字表示完成所有料理需要多少种不同的材料。
BUTTER FLOUR HONEY FLOUR EGG
4
代码清单:
#include
#include
每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 75),表示田地的大小,接下来的 n 行,每行包含 m 个 0-9 之间的数字,表示每块位置的价值。
输出一行表示牛牛所能取得的最大的价值。
4 4 3332 3233 3332 2323
2
可行性判断:假定二分值为mid。暴力枚举竖切的位置,然后看横切能切多少刀。枚举横切时,当这部分的4个矩形的价值都大于等于mid,说明这一刀切得合理,从这个位置开始继续往下枚举横切。如果最终横切的刀数大于等于4,那么说明这个值mid是合理的,否则不合理。通过这样的不断压缩区间,最终必然能够得到答案。
其中如何巧妙计算每个小矩形的和,也是可以通过预处理然后得到的。具体可见代码。
代码清单:
#include
#include
#include
#include
using namespace std;
const int maxn = 75 + 5;
int n, m;
char str[maxn];
int a[maxn][maxn];
int sum[maxn][maxn];
void input() {
for(int i = 1; i <= n; ++i) {
scanf("%s", str + 1);
for(int j = 1; j <= m; ++j) {
a[i][j] = str[j] - '0';
}
}
}
int getArea(int x1, int y1, int x2, int y2) {
return (sum[x2][y2] - sum[x2][y1] - sum[x1][y2] + sum[x1][y1]);
}
bool judge(int mid) {
for(int j1 = 1; j1 <= m - 3; ++j1) {
for(int j2 = j1 + 1; j2 <= m - 2; ++j2) {
for(int j3 = j2 + 1; j3 <= m - 1; ++j3) {
int prei = 0, cnt = 0;
for(int i = 1; i <= n; ++i) {
int cube1 = getArea(prei, 0, i, j1);
int cube2 = getArea(prei, j1, i, j2);
int cube3 = getArea(prei, j2, i, j3);
int cube4 = getArea(prei, j3, i, m);
if(cube1 >= mid && cube2 >= mid && cube3 >= mid && cube4 >= mid) {
prei = i;
cnt += 1;
}
}
if(cnt >= 4) return true;
}
}
}
return false;
}
void solve() {
memset(sum, 0, sizeof(sum));
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];
}
}
int l = 0, r = sum[n][m], mid;
int ans = 0;
while(l <= r) {
mid = (l + r) >> 1;
if(judge(mid)) {
l = mid + 1;
ans = mid;
}
else {
r = mid - 1;
}
}
printf("%d\n", ans);
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
input();
solve();
}
return 0;
}
每个输入包含一个测试用例。每个测试用例的第一行包含一个整数 n(1 <= n <= 100),接下来的一行包含 n 个整数 ai(1 <= ai <= 100)。
输出一行表示最少需要移动多少次可以平分苹果,如果方案不存在则输出 -1。
4 7 15 9 5
3
首先判断不存在的情况。
1)当总和不能均分时;
2)当数据中同时出现了偶数以及奇数时;
3)当所有数为偶数并且总和均分为奇数 or 所有数为奇数并且总和均分为偶数时;
以上任一条件满足的时候直接输出-1即可。
否则,一遍循环找比均分值大的数,然后相减除2,累计即可。
代码清单:
#include
#include
每个输入包含一个测试用例。每个测试用例包含一行一个整数 h (1 <= h <= 10^18)。
输出一行一个整数表示结果。
10
2
代码清单:
#include
#include
每个输入包含一个测试用例。每个测试用例包含两行长度不超过 10 的不包含空格的可见 ASCII 字符串。
输出一行 “Yes” 或者 “No” 表示结果。
x.nowcoder.com ooo
Yes
代码清单:
#include
#include
每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。
输出一行表示合法的排列数目。
5 5 4 0 0 2 0
2
总顺序对 = 已知数间的顺序对 + 未知数间的顺序对 + 已知数和未知数间的顺序对;第一部分可以先求出来 O(100^2),第二部分在每次暴力枚举时可以求出 O(55),关键是第三部分,我们可以这样预处理,计算出每个未知数在每个位置上与已知数之间产生的顺序对数,这个是可以做到的,即算左边比它小的数有多少,右边算比它大的数。时间复杂度大概也就在O(10 * 100)。这样算来总的复杂度为:O(10! * 55),是可以通过的。
代码清单:
#include
#include
题目链接:http://www.nowcoder.com/test/2252286/summary