在二维平面坐标系中,已知存在一条线段(图中P1->p2)和一个矩形区域,编程计算得出线段被矩形区域裁剪的新起始点。
注意以下要求:
A、线段是有方向的,裁剪得到的新线段也需要保持原线段的方向;下图中,线段的描述是P1->p2,则裁剪的结果是P3->p4,反之,如果线段描述是P2->P1,则结果是P4->P3
B、线段的起始点在矩形区域里面时,裁剪的结果则就是原始线段
C、当线段与矩形区域没有相交线段的时候,结果输出“-1”
#include
using namespace std;
struct Point {
float x, y;
};
struct Rect {
Point leftBottom, rightTop;
bool contain(const Point& pt) {
return pt.x > leftBottom.x&& pt.xleftBottom.y&& pt.y < rightTop.y;
}
void cut(Point& pt, const Point& dir) { //根据方向向量将点裁剪到矩形上
if (contain(pt)) //如果点在矩形内,则不需要对它裁剪
return;
Point offset = { 1,dir.y / dir.x }; //确定水平方向,计算垂直方向的偏移
if (pt.x > rightTop.x)
pt = { rightTop.x,pt.y + offset.y * (rightTop.x - pt.x) };
else if (pt.x < leftBottom.x)
pt = { leftBottom.x,pt.y + offset.y * (leftBottom.x - pt.x) };
offset = { dir.x / dir.y,1 }; //确定垂直方向,计算水平方向的偏移
if (pt.y > rightTop.y)
pt = { pt.x + offset.x * (rightTop.y - pt.y), rightTop.y };
else if (pt.y < leftBottom.y)
pt = { pt.x + offset.x * (leftBottom.y - pt.y), leftBottom.y };
}
};
istream& operator>>(istream& in, Point& pt) {
in >> pt.x >> pt.y;
return in;
}
int main() {
Rect rect;
Point p1, p2;
Point dir; //直线的方向向量
cin >> rect.leftBottom >> rect.rightTop;
cin >> p1 >> p2;
dir = { p2.x - p1.x,p2.y - p1.y };
rect.cut(p1, dir);
rect.cut(p2, dir);
if (p1.x == p2.x && p1.y == p2.y)
printf("-1");
else
printf("(%0.2f,%0.2f)\n(%0.2f,%0.2f)", p1.x, p1.y, p2.x, p2.y);
return 0;
}
给定一个M行N列表格,从左上角单元格开始,每次只能向右或者向下走,最后到达右下角单元格位置,路径上所有单元格内字符串拼接起来就是路径字符串,求所有路径中路径字符串字符长度最短的路径字符串的长度。
如给定3行4列表格(m=3,n=4),各单元格字符串内容如下表所示,那么表中箭头所指的路径(灰色背景单元格)即为最短路径,对应的内容为粗斜体字符串即“武汉金山办公公司”长度为8,最终的结果也就是这个字符串。
要求:
输入:strTableContent为表格字符串表示,使用“|”作为单元格分隔符,“/”作为表格行分隔符,将表格从左向右,从上向下依次序列化,如下标的字符串表示为:
strTableContent=”武汉|金山|办公|/金山办公|办|软件|有限/软件有限公司|公||公司/”;
输出:GetMinPathStringLength 返回结果为”8”;
输入例子1:
3,4,"wh|js|bg|/jsbg|b|rj|yx/rjyxgs|g||gs/"
输出例子1:
8
例子说明1:
#include
#include
#include
#include
#include
using namespace std;
class Solution {
public:
int GetMinPathStringLength(int m, int n, string strTableContent) {
vector> graph;
int minSize = numeric_limits::max();
int count = 0;
vector row;
for (char& ch : strTableContent) {
if (ch == '|') {
row.push_back(count);
count = 0;
}
else if (ch == '/') {
row.push_back(count);
count = 0;
graph.push_back(row);
row.clear();
}
else
count++;
}
vector> dp(m ,vector(n));
dp[0][0] = graph[0][0];
for (int i = 1; i < m; i++)
dp[i][0] = graph[i][0] + dp[i - 1][0];
for (int i = 1; i < n; i++)
dp[0][i] = graph[0][i] + dp[0][i - 1];
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + graph[i][j];
}
}
return dp[m-1][n-1];
}
};
int main() {
Solution s;
s.GetMinPathStringLength(3, 4, "wh|js|bg|/jsbg|b|rj|yx/rjyxgs|g||gs/");
}
字符串联想是一个被广泛用于搜索引擎/输入法的功能。联想算法根据一定规则,计算出与待匹配字符串最接近的若干个联想结果。聪明的ttt觉得这功能很好,希望刚入职的lhy也实现一个简单的联想算法。
ttt:客户端将提供一个最优匹配结果数k,一个待匹配字符串,和若干个命令。希望你能实现一个算法,它实现两种操作:
A: 增加一项搜索记录
P: 打印当前的k个最优匹配结果
我们规定每个匹配记录(record)需满足:record中存在至少一个与s完全匹配的子串。
并规定,若满足下列条件,则称record a是比record b更好的匹配记录
1.record a长度短于record b
2.长度相同,record a的字典序小于record b
这可把热爱摸鱼的lhy难倒了。为了帮lhy保住工作,和ttt一样聪明的你能帮帮lhy吗?
输入描述:
输入数据包含n + 3行每一组数据由三行组成
第一行:n
第二行:k
第三行:s
第四行~n+3行:
[A record] 或 [P]
n: 需执行的总命令数 (n < 10000)k:需要输出的总匹配记录数目(0 输入数据保证每条字符串长度 (0 < length < 100),且仅由小写ANSI字符组成 输出描述: 每次P命令执行后,输出 P: k行数据(不允许有重复数据,相同的看做同一条数据)。 不足k行则输出所有符合题干条件的记录。 输出顺序需按提干条件由优先级高->低顺序排列 输入例子1: 输出例子1: 输入例子2: 输出例子2: 某地主担心农民偷取他的粮食,雇人挖了大量地窖来屯粮,这些地窖层层排列,只有一个总入口。 每个地窖都有一个随机且唯一的数字编号(1 ... N)。聪明的农夫经过一番侦察,发现所有的地窖形成了一颗满二叉树,只有叶子节点中才存放有粮食,粮食数量与地窖编号相同。 狡猾的地主设置了报警装置,只要任意两个相邻的叶子节点中粮食被偷,就会自动报警。 输入描述: 第一行输入一个数字n表示有n个节点的满二叉树 第二行n个数字a[0],a[1]...a[n-1]用空格隔开,表示二叉树的前序遍历 第三行n个数字b[0],b[1]...b[n-1]用空格隔开,表示二叉树的中序遍历 数据范围: 3<=n<=105 且n可以表示成2k-1(k为整数) a[0]...a[n-1]中1,2...n每个数字分别出现一次 b[0]...b[n-1]中1,2...n每个数字分别出现一次 输出描述: 输入例子1: 输出例子1: 6
3
wps
A ttt.smart
A lhy.stupid.wps
P
A lhy.stupid.wps
A wps.cn
P
P:
lhy.stupid.wps
P:
wps.cn
lhy.stupid.wps
4
1
ttt
P
A tttnba
A ttttql
P
P:
P:
tttnba
#include
14、遍历二叉树
农夫事先并不知道地窖分布图,但是他无意间得到了地窖组成的二叉树的前序遍历和中序遍历结果,请帮忙计算一下,在不触发报警装置的情况下,农夫最多可以偷取地主多少粮食。
提示:
输出一个数字,表示农夫最多可以偷取地主多少粮食
3
2 1 3
1 2 3
3
#include