相邻数对 (100)

给定 n 个不同的整数,询问这些数中有多少对整数,它们的值正好相差 1。

输入格式:

  • 第一行包含一个整数 n,表示给定整数的个数。
  • 第二行包含所给定的 n 个整数。

输出格式:

  • 输出一个整数,表示值正好相差 1 的数对的个数。

数据范围:

  • 1 ≤ n ≤ 1000
  • 给定的整数为不超过 10000 的非负整数。

输入样例:

6
10 2 6 3 7 8

输出样例:

3

样例解释: 值正好相差 1 的数对包括 (2,3), (6,7), (7,8)。

题目分析

Sort

代码实现

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;

int a[N], n;
int main () {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> a[i];
    sort(a, a + n);
    int res = 0;
    for (int i = 0; i < n - 1; ++i)
        if(a[i + 1] - a[i] == 1) ++res;
    cout << res;
    return 0;
} 

画图 (100)

在一个定义了直角坐标系的纸上,画一个 (x1,y1) 到 (x2,y2) 的矩形指将横坐标范围从 x1x2,纵坐标范围从 y1y2 之间的区域涂上颜色。

下图给出了一个画了两个矩形的例子。

image

第一个矩形是 (1,1) 到 (4,4),用绿色和紫色表示。

第二个矩形是 (2,3) 到 (6,5),用蓝色和紫色表示。

图中,一共有 15 个单位的面积被涂上颜色,其中紫色部分被涂了两次,但在计算面积时只计算一次。

给出所有要画的矩形,请问总共有多少个单位的面积被涂上颜色。

输入格式:

  • 输入的第一行包含一个整数 n,表示要画的矩形的个数。
  • 接下来 n 行,每行 4 个非负整数,分别表示要画的矩形的左下角的横坐标与纵坐标,以及右上角的横坐标与纵坐标。

输出格式:

  • 输出一个整数,表示有多少个单位的面积被涂上颜色。

数据范围:

  • 1 ≤ n ≤ 100
  • 0 ≤ 横坐标、纵坐标 ≤ 100

输入样例:

2
1 1 4 4
2 3 6 5

输出样例:

15

题目分析

前缀和 差分

代码实现

#include <iostream>
#include <cstring>
using namespace std;
const int N = 110;

int g[N][N], n, x1, y1, x2, y2;
void add() {
    ++x1, ++y1;
    ++g[x1][y1];
    --g[x1][y2 + 1];
    --g[x2 + 1][y1];
    ++g[x2 + 1][y2 + 1];
}
int main () {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    while(n--) {
        cin >> x1 >> y1 >> x2 >> y2;
        add();
    }
    int res = 0;
    for (int i = 1; i < N; ++i) {
        for (int j = 1; j < N; ++j) {
            g[i][j] += g[i - 1][j] + g[i][j - 1] - g[i - 1][j - 1];
            if(g[i][j]) ++res;
        }
    }
    cout << res;
    return 0;
} 

字符串匹配 (100)

给出一个字符串 S,由大小写英文字母组成。

输入的第一行包含一个字符串 S,由大小写英文字母组成。

第二行包含一个数字,表示大小写敏感的选项,当数字为 0 时表示大小写不敏感,当数字为 1 时表示大小写敏感。

第三行包含一个整数 n,表示给出的文字的行数。

接下来 n 行,每行包含一个字符串,字符串由大小写英文字母组成,不含空格和其他字符。

输出格式: 输出多行,每行包含一个字符串,按出现的顺序依次给出那些包含了字符串 S 的行。

数据范围: 1 ≤ n ≤ 100 每个字符串的长度不超过 100

输入样例:

Hello
1
5
HelloWorld
HiHiHelloHiHi
GrepIsAGreatTool
HELLO
HELLOisNOTHello

输出样例:

HelloWorld
HiHiHelloHiHi
HELLOisNOTHello

样例解释: 在上面的样例中,第四个字符串虽然也是 Hello,但是大小写不正确。

如果将输入的第二行改为 0,则第四个字符串应该输出。

题目分析

KMP

代码实现

#include <iostream>
#include <cstring>
using namespace std;
const int N = 110;

int ne[N], n, m, op, cy;
string p, s, buf;
void trans(string& s) {
    for (auto& ch : s) 
        if(ch >= 'A' && ch <= 'Z') ch += 32;

}
bool kmp() {
    for (int i = 1, j = 0; i <= m; ++i) {
        while(j && s[i] != p[j + 1]) j = ne[j];
        if(s[i] == p[j + 1]) ++j;
        if(j == n) return 1;
    }
    return 0;
}
int main () {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> buf;
    cin >> op >> cy;
    n = buf.length();
    if(!op) trans(buf);
    p = " ";
    p += buf;
    for (int i = 2, j = 0; i <= n; ++i) {
        while(j && p[i] != p[j + 1]) j = ne[j];
        if(p[i] == p[j + 1]) ++j;
        ne[i] = j;
    }
    while(cy--) {
        cin >> buf;
        string ans = buf;
        m = buf.length();
        if(!op) trans(buf);
        s = " ";
        s += buf;
        if(kmp()) cout << ans << '\n';
    }
    return 0;
} 

最优配餐 (100)

栋栋最近开了一家餐饮连锁店,提供外卖服务。

随着连锁店越来越多,怎么合理的给客户送餐成为了一个急需解决的问题。

栋栋的连锁店所在的区域可以看成是一个 n×n 的方格图(如下图所示),方格的格点上的位置上可能包含栋栋的分店(绿色标注)或者客户(蓝色标注),有一些格点是不能经过的(红色标注)。 image 送餐的主要成本体现在路上所花的时间,每一份餐每走一个单位的距离需要花费 1 块钱。

每个客户的需求都可以由栋栋的任意分店配送,每个分店没有配送总量的限制。

现在你得到了栋栋的客户的需求,请问在最优的送餐方式下,送这些餐需要花费多大的成本。

输入格式: 输入的第一行包含四个整数 n, m, k, d,分别表示方格图的大小、栋栋的分店数量、客户的数量,以及不能经过的点的数量。

接下来 m 行,每行两个整数 xi, yi,表示栋栋的一个分店在方格图中的横坐标和纵坐标。

接下来 k 行,每行三个整数 xi, yi, ci,分别表示每个客户在方格图中的横坐标、纵坐标和订餐的量。(注意,可能有多个客户在方格图中的同一个位置)

接下来 d 行,每行两个整数,分别表示每个不能经过的点的横坐标和纵坐标。

输出格式: 输出一个整数,表示最优送餐方式下所需要花费的成本。

数据范围: 前 3 前 6 所有评测用例都满足:1≤n≤1000, 1≤m, k, d≤n^2, 1≤xi, yi≤n。 可能有多个客户在同一个格点上。 每个客户的订餐量不超过 1000,每个客户所需要的餐都能被送到。

输入样例:

10 2 3 3
1 1
8 8
1 5 1
2 3 3
6 7 2
1 2
2 2
6 8

输出样例:

29

题目分析

多源BFS

代码实现

#include <iostream>
#include <cstring>
#include <queue>
#define x first 
#define y second
using namespace std;
using PII = pair <int,int>;
using LL = long long;
const int N = 1010, M = N * N;

int n, m, k, d, x, y, z, dist[N][N], cs[M][3];
bool g[N][N];
PII dir[4] = {{0,1},{1,0},{0,-1},{-1,0}};
queue <PII> que;
void bfs() {
    while(que.size()) {
        PII t = que.front(); que.pop();
        for(int k = 0; k < 4; ++k) {
            int I = t.x + dir[k].x, J = t.y + dir[k].y;
            if(g[I][J]) {
                if(dist[I][J] > dist[t.x][t.y] + 1) {
                    dist[I][J] = dist[t.x][t.y] + 1;
                    que.push({I,J});
                }
            }
        }
    }
}
int main () {
    ios::sync_with_stdio(0);
    cin.tie(0);
    memset(dist, 0x3f, sizeof dist);
    cin >> n >> m >> k >> d;
    for (int i = 1; i <= n; ++i) 
        for(int j = 1; j <= n; ++j)
            g[i][j] = 1;
    for(int i = 0; i < m; ++i) {
        cin >> x >> y;
        que.push({x,y});
        dist[x][y] = 0;
    }
    for(int i = 0; i < k; ++i) {
        cin >> cs[i][0] >> cs[i][1] >> cs[i][2];
    }
    while(d--) {
        cin >> x >> y;
        g[x][y] = 0;
    }
    bfs();
    LL res = 0;
    for(int i = 0; i < k; ++i)
        res += dist[cs[i][0]][cs[i][1]] * cs[i][2];
    cout << res;
    return 0;
} 

拼图 (20)

给出一个 n×m 的方格图,现在要用如下 L 型的积木拼到这个图中,使得方格图正好被拼满,请问总共有多少种拼法。

其中,方格图的每一个方格正好能放积木中的一块。 image 输入格式: 输入的第一行包含两个整数 n,m,表示方格图的大小。

输出格式: 输出一行,表示可以放的方案数,由于方案数可能很多,所以请输出方案数除以 10^9+7 的余数。

数据范围: 在评测时将使用 10 个评测用例对你的程序进行评测。 评测用例 1 和 2 满足:1≤n≤30,m=2。 评测用例 3 和 4 满足:1≤n,m≤6。 评测用例 5 满足:1≤n≤100,1≤m≤6。 评测用例 6 和 7 满足:1≤n≤1000,1≤m≤6。 评测用例 8、9 和 10 满足:1≤n≤10^15,1≤m≤7。

输入样例:

6 2

输出样例:

4

样例解释: 四种拼法如下图所示: image

题目分析

思维题 快速幂 DP, 没做出来。。。错误代码过于先进,不便展示。


0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注

友情链接:Ctips' blog, Colza’s blog

站点状态:Status