目录
第一题
一个串的子串是指该串的一个连续的局部。如果不要求连续,则可称为它的子序列。
比如对串: "abcdefg" 而言,"ab","abd","bdef" 等都是它的子序列。
特别地,一个串本身,以及空串也是它的子序列。对两个串而言,可以有许多的共同的子序列,我们关心的是:它们所共同拥有的长度最大的子序列是多长。以下代码实现了这个问题的求解。请填写划线部分缺失的代码。
注意:只填写划线部分缺少的内容,不要填写任何多余的符号或注释、说明等。例如,不要填写已经给出的小括号。
inline max(int a, int b) { return a>b?a:b; } int f(char* x, char* y) { if(strlen(x)==0) return 0; if(strlen(y)==0) return 0; if(*x == *y) return f(x+1, y+1) + 1; return max( ______________________ ); } int main() { printf("%d\n", f("ac","abcd")); //2 printf("%d\n", f("acebbcde1133","xya33bc11de")); //5 return 0; }
思路:
当*x = *y的时候,继续比较*(x+1) 和 *y+1相不相等
如果不相等,则比较 *x 和 *(y+1) 、 *(x+1) 和 *y
比如:"ab" 和 "abc"
//答案:
return max( f(x+1,y), f(x,y+1) );
第二题
历史上有许多计算圆周率pai的公式,其中,格雷戈里和莱布尼茨发现了下面的公式:
pai = 4*(1-1/3+1/5-1/7 ....)
参见【图1.png】
![]()
图1 这个公式简单而优美,但美中不足,它收敛的太慢了。
如果我们四舍五入保留它的两位小数,那么:累积了1项和是:4.00
累积了2项和是:2.67
累积了3项和是:3.47
。。。请你写出它累积了100项的和是多少(四舍五入到小数后两位)。
注意:只填写该小数本身,不要填写任何多余的说明或解释文字。
答案:3.13
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double pai = 0;
for (int i = 1; i <= 100; i++)
{
double t = 1.0 / (2*i-1);
if((i&1) == 0)
t = -t;
pai += t;
}
cout << fixed << setprecision(2) << pai*4 << endl;
system("pause");
}
第三题
如果x的x次幂结果为10(参见【图1.png】),你能计算出x的近似值吗?
显然,这个值是介于2和3之间的一个数字。
请把x的值计算到小数后6位(四舍五入),并填写这个小数值。
注意:只填写一个小数,不要写任何多余的符号或说明。
答案:2.506184
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
for (double x = 2; x <= 3 ; x+=0.00000001)
{
if(fabs(pow(x,x) - 10 )< 0.000001)
cout << fixed << setprecision(6) << x << endl;
}
system("pause");
}
第四题
今有7对数字:两个1,两个2,两个3,...两个7,把它们排成一行。
要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:17126425374635
当然,如果把它倒过来,也是符合要求的。
请你找出另一种符合要求的排列法,并且这个排列法是以74开头的。
注意:只填写这个14位的整数,不能填写任何多余的内容,比如说明注释等。
答案:74151643752362
方法(1):快乐暴力
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
char s[] = "74112233455667";
do
{
int p,q;
bool flag = true;
for (char i = '1'; i <= '7'; i++)
{
for(int j = 0; j < 14; j++) //正序找
if(s[j] == i)
{
p = j;
break;
}
for (int j = 13; j >= 0; j--) //反序找
if(s[j] == i)
{
q = j;
break;
}
if(q - p != i-48+1) //看相同数字相间 有多少数字
{
flag =false;
break;
}
}
if(flag)
cout << s << endl;
} while(next_permutation(s+2,s+14));
system("pause");
}
方法(2):dfs
#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
#include <iterator>
using namespace std;
int a[20];
void dfs(int t)
{
if(t == 4)
dfs(t + 1);
if(t > 6)
{
copy(a,a+14, ostream_iterator<int>(cout));
}
for (int i = 2; i < 14; i++)
{
if ( (i+t+1) < 14 && a[i] == 0 && a[i+t+1] == 0)
{
a[i] = a[i+t+1] = t;
dfs(t + 1);
a[i] = a[i+t+1] = 0;
}
}
}
int main()
{
a[0] = a[8] = 7;
a[1] = a[6] = 4;
dfs(1);
system("pause");
}
第五题
勾股定理,西方称为毕达哥拉斯定理,它所对应的三角形现在称为:直角三角形。已知直角三角形的斜边是某个整数,并且要求另外两条边也必须是整数。
求满足这个条件的不同直角三角形的个数。
【数据格式】
输入一个整数 n (0<n<10000000) 表示直角三角形斜边的长度。
要求输出一个整数,表示满足条件的直角三角形个数。例如,输入:
5
程序应该输出:
1
再例如,输入:
100
程序应该输出:
2
再例如,输入:
3
程序应该输出:
0
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
long long m;
int count = 0;
cin >> m;
int t = m*m;
for (long long i = 1; i < m; i++)
{
long long j = sqrt(t - i*i);
if( j*j + i*i == t)
count++;
}
cout << count/2;
system("pause");
}
第六题
你一定听说过“数独”游戏。
如【图1.png】,玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个同色九宫内的数字均含1-9,不重复。数独的答案都是唯一的,所以,多个解也称为无解。
本图的数字据说是芬兰数学家花了3个月的时间设计出来的较难的题目。但对会使用计算机编程的你来说,恐怕易如反掌了。
本题的要求就是输入数独题目,程序输出数独的唯一解。我们保证所有已知数据的格式都是合法的,并且题目有唯一的解。
格式要求:
输入9行,每行9个数字,0代表未知,其它数字为已知。
输出9行,每行9个数字表示数独的解。例如:
输入(即图中题目):005300000 800000020 070010500 400005300 010070006 003200080 060500009 004000030 000009700
程序应该输出:
145327698 839654127 672918543 496185372 218473956 753296481 367542819 984761235 521839764
再例如,输入:
800000000 003600000 070090200 050007000 000045700 000100030 001000068 008500010 090000400
程序应该输出:
812753649 943682175 675491283 154237896 369845721 287169534 521974368 438526917 796318452
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
#include <iostream>
using namespace std;
char map[10][10];
bool check(int x,int y,char ch)
{
for (int j = 0; j < 9; j++)
{
if(map[x][j] == ch || map[j][y] == ch)
{
return false;
}
}
int tx = x/3*3;
int ty = y/3*3;
for (int i = tx; i < tx+3; i++)
{
for (int j = ty; j < ty+3; j++)
{
if(map[i][j] == ch)
return false;
}
}
return true;
}
void dfs(int x,int y)
{
if(y > 8)
{
for (int i = 0; i < 9; i++)
cout << map[i] << endl;
return;
}
if(map[x][y] == '0')
{
for (char i = '1'; i <= '9'; i++)
{
if(check(x,y,i) == true)
{
map[x][y] = i;
dfs( (x + 1) % 9, y + (x + 1) / 9);
map[x][y] = '0';
}
}
}
else
{
dfs( (x + 1) % 9, y + (x + 1) / 9);
}
}
int main()
{
for (int i = 0; i < 9; i++)
cin >> map[i];
dfs(0,0);
system("pause");
}
第七题
G将军有一支训练有素的军队,这个军队除开G将军外,每名士兵都有一个直接上级(可能是其他士兵,也可能是G将军)。现在G将军将接受一个特别的任务,需要派遣一部分士兵(至少一个)组成一个敢死队,为了增加敢死队队员的独立性,要求如果一名士兵在敢死队中,他的直接上级不能在敢死队中。
请问,G将军有多少种派出敢死队的方法。注意,G将军也可以作为一个士兵进入敢死队。
输入格式
输入的第一行包含一个整数n,表示包括G将军在内的军队的人数。军队的士兵从1至n编号,G将军编号为1。
接下来n-1个数,分别表示编号为2, 3, ..., n的士兵的直接上级编号,编号i的士兵的直接上级的编号小于i。
输出格式
输出一个整数,表示派出敢死队的方案数。由于数目可能很大,你只需要输出这个数除10007的余数即可。
样例输入13 1 1
样例输出1
4
样例说明
这四种方式分别是:
1. 选1;
2. 选2;
3. 选3;
4. 选2, 3。
样例输入27 1 1 2 2 3 3
样例输出2
40
数据规模与约定
对于20%的数据,n ≤ 20;
对于40%的数据,n ≤ 100;
对于100%的数据,1 ≤ n ≤ 100000。
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
方法(1):
#include <iostream>
#include <cstring>
using namespace std;
int m,grade[100005],flag[100005],a[100];
int count = 0;
void dfs(int step,int end)
{
if (step == end+1)
{
/* 打印加入敢死队士兵的名单
for (int i = 1; i < step; i++)
cout << a[i];
cout << endl;
*/
count++;
return;
}
for (int i = 1; i <= m; i++)
{
if(flag[i] == 0) //如果i号士兵没有被选择
{
if(flag[ grade[i] ] == false && i > a[step-1]) //检查:i号士兵的上级 是否加入敢死队;
//i > a[step-1]: 是为了保证不会出现重复序列,比如有了123,就不能有312;
{
flag[i] = 1;
a[step] = i;
dfs(step + 1, end);
flag[i] = 0 ;
}
}
}
}
int main()
{
cin >> m;
grade[1] = 0; //将军的上级 为0号
for (int i = 2; i <= m; i++)
{
cin >> grade[i]; // i号士兵 的 上级 为,grade[i]
}
for (int i = 1; i <= m; i++) // 选择1个士兵加入敢死队 到 选择m个士兵加入敢死队
{
memset(flag,0,sizeof(flag)); //每次清空标志位
dfs(1,i);
}
cout << count % 10007 << endl;
system("pause");
}
方法(2):
参考文章:https://blog.csdn.net/lauraliu123/article/details/54911903
https://www.cnblogs.com/pengchuan/p/8635514.html
#include <stdio.h>
int n,a[100001],x[100001];
int sum=0;
bool place(int c,int b)
{
if(b==1&&x[a[c]]==1)
return false;
return true;
}
void dfs(int t){
if(t>n)
{
sum++;
}
else
{
for(int i=1;i>=0;i--) //来 或者 不来 两种情况
{
if(place(t,i))
{
x[t]=i;
dfs(t+1);
}
else
continue;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=2;i<=n;i++)
scanf("%d",&a[i]);
dfs(1);
sum--;
printf("%d",sum%10007);
return 0;
}