数学 | 2015.计算机院.Problem A.求导数
描述:求函数f(x) = ax3 + bx2 + c*x + d在x =
x
0
x_0
x0处的一阶导数。
输入:a b c d
x
0
x_0
x0。
输出:f’(
x
0
x_0
x0)。
样例输入:1 1 1 1 1
样例输出:6
#include <iostream>
using namespace std;
int main()
{
int T;
cin >> T;
int a, b, c, d, x0;
while( T-- )
{
cin >> a >> b >> c >> d >> x0;
int diravtives = 3*a*x0*x0 + 2*b*x0 + c;
cout << diravtives << endl;
}
return 0;
}
模拟 | 2015.计算机院.Problem B.LIST
描述:在该LIST上实现3种操作
1、append x在该LIST末尾添加x,x是32位整数
2、pop删除该LIST末尾的数
3、find i寻找第i个数,若i为负数表示寻找倒数第i个数,例如i = -1表示寻找倒数第一个
输入:第一行输入一个m,表示有m条操作,接下来每行输入一条操作
输出:输出find i找到的数
输入范例
2
5
append 1
append 2
find 1
find -1
pop
6
append 1
append 2
append 3
append 4
find -2
find 2
代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int T;
cin >> T;
int N;
string cmd;
int arg;
vector<int> list;
while( T-- )
{
list.clear();
cin >> N;
while( N-- )
{
cin >> cmd;
if( cmd == "append" )
{
cin >> arg;
list.push_back( arg );
}
else if( cmd == "find" )
{
cin >> arg;
if( arg > 0 )
cout << list[arg] << endl;
else
cout << list[list.size()+arg] << endl;
}
else
list.erase( list.end()-1 );
}
}
return 0;
}
DP | 2015.计算机院.Problem C.图像压缩存储
描述:以二维数组表示图像,其值只有0、1两种,寻找两幅图像中最大的相同部分
输入:第一行输入一个n,接下来的2n行输入两个n * n数组,寻找一个最大的m * m子区域,使得两个数组在该子区域完全相同
输出:输出上述m
样例输入:
4
1 1 1 1
1 1 1 0
1 1 1 0
1 1 1 1
0 1 1 1
0 1 1 1
0 1 1 1
0 1 1 0
样例输出:
2
解释:上述两个4阶数组中的一个2阶子区域(第1、2行,第2、3列完全相同)
思路:
可以将两个矩阵直接异或(^)出来。
0异或0等于0
1异或1等于0
0异或1等于1
(相同异或为0,不同异或为1)
两个矩阵异或之后取非。
然后题目就变成了求第三个矩阵里的最大的为1的方阵。
算法:以矩阵中每一个点作为正方形右下角点来处理,
当该点为1时,以该点为右下角点的最大边长最多比以它的左方、上方和左上方为右下角的正方形边长多1,
即如果该点左上的三个点有值为0的点,当前点所在的全为1的正方形最大边长只能为1,
所以这时只能取另外三个正方形中最小的正方形边长+1。
用d[i][j]表示以i,j坐标为右下角的正方形最大边。
则有状态转移方程:dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1])) + 1
https://blog.csdn.net/Broken_Wave/article/details/81951159
我们可以采用动态规划的思想。
首先从左到右遍历一次寻找每个点可以向左延伸到最远的距离。
然后从上到下遍历一次寻找每个点可以向上延伸到最远的距离。
最后直接从左上角到右下角。看直接能到最左上角的距离。
就是每个点可以延伸最大的方阵的边长。
代码
#include <iostream>
using namespace std;
const int maxn = 50;
int n;
int matrix[maxn][maxn];
int dp[maxn][maxn];
int main()
{
int T, i, j;
cin >> T;
while( T-- )
{
cin >> n;
for( i = 0; i < n; i++ )
for( j = 0; j < n; j++ )
cin >> matrix[i][j];
int temp;
for( i = 0; i < n; i++ )
for( j = 0; j < n; j++ )
{
cin >> temp;
matrix[i][j] = !( matrix[i][j]^temp );
}
int res = 0;
for ( i=0; i<n; i++) {
if (matrix[i][0] == 1) {
dp[i][0] = 1;
res = 1;
}
}
for ( j=0; j<n; j++) {
if (matrix[0][j] == 1) {
dp[0][j] = 1;
res = 1;
}
}
for ( i=1; i<n; i++) {
for ( j=1; j<n; j++) {
if (matrix[i][j] == 1) {
dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1])) + 1;
}
res = max(res, dp[i][j]);
}
}
cout << res << endl;
}
return 0;
}
构造| 栈 | 2015.计算机院.Problem D.解析表达式
描述:输入一个字符串形式的表达式,该表达式中包括整数,四则运算符(+、-、*、/),括号,三角函数(sin(x)、cos(x)、tan(x)),底数函数(lg(x)、ln(x)),计算该表达式的值
输入:输入一个字符串形式的表达式,保证中间及最终结果不超出double的范围
输出:表达式的值,保留6位小数
样例输入:
3
3+5
((2-1)*5-1)*6
1+cos(0)
sin(sin(1-1))
样例输出:
3.000000
8.000000
24.000000
2.000000
0.000000
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cmath>
using namespace std;
char s[1000];
int g_pos; // 字符数组的下标
/* 字符转数字 */
double Translation(int & pos)
{
double integer = 0.0; // 整数部分
double remainder = 0.0; // 余数部分
while (s[pos] >= '0' && s[pos] <= '9')
{
integer *= 10;
integer += (s[pos] - '0');
pos++;
}
if (s[pos] == '.')
{
pos++;
int c = 1;
while (s[pos] >= '0' && s[pos] <= '9')
{
double t = s[pos] - '0';
t *= pow(0.1, c);
c++;
remainder += t;
pos++;
}
}
return integer + remainder;
}
/* 返回运算符级别 */
int GetLevel(char ch)
{
switch (ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return 0;
case '#':
return -1;
};
}
/* 对两个数进行运算 */
double Operate(double a1, char op, double a2)
{
switch (op)
{
case '+':
return a1 + a2;
case '-':
return a1 - a2;
case '*':
return a1 * a2;
case '/':
return a1 / a2;
};
}
/* 利用两个栈进行模拟计算 */
double Compute()
{
stack<char> optr; // 操作符栈
stack<double> opnd; // 操作数栈
optr.push('#'); //置于符栈顶
int len = strlen(s);
bool is_minus = true; // 判断'-'是减号还是负号, true表示负号
for (g_pos = 0; g_pos < len;)
{
//1. 负号
if (s[g_pos] == '-' && is_minus) // 是负号
{
opnd.push(0);
optr.push('-');
g_pos++;
}
//2. 是右括号 )
else if (s[g_pos] == ')')
{
is_minus = false;
g_pos++;
while (optr.top() != '(')
{
double a2 = opnd.top();
opnd.pop();
double a1 = opnd.top();
opnd.pop();
char op = optr.top();
optr.pop();
double result = Operate(a1, op, a2);
opnd.push(result);
}
optr.pop(); // 删除'('
}
//3. 数字
else if (s[g_pos] >= '0' && s[g_pos] <= '9')
{
is_minus = false;
opnd.push(Translation(g_pos));
}
//4. ( 左括号
else if (s[g_pos] == '(')
{
is_minus = true;
optr.push(s[g_pos]);
g_pos++;
}
//5. + - * / 四种
else
{
while (GetLevel(s[g_pos]) <= GetLevel(optr.top())) //当前优先级小于栈尾优先级
{
double a2 = opnd.top();
opnd.pop();
double a1 = opnd.top();
opnd.pop();
char op = optr.top();
optr.pop();
double result = Operate(a1, op, a2);
opnd.push(result);
}
optr.push(s[g_pos]);
g_pos++;
}
}
while (optr.top() != '#')
{
double a2 = opnd.top();
opnd.pop();
double a1 = opnd.top();
opnd.pop();
char op = optr.top();
optr.pop();
double result = Operate(a1, op, a2);
opnd.push(result);
}
return opnd.top();
}
int main()
{
while (cin >> s)
cout << "结果为:" << Compute() << endl << endl;
return 0;
}