一、星号阵列-18
描述
输入一个不小于6的偶数,输出如下星号阵列。周围一圈是*;正中间两横两竖是+;然后四个角落根据方位,按照类似坐标系的象限,输出1、2、3、4。
例如输入8时,应输出:
输入
只有一组案例。
一个正整数n,表示阵列的宽度和高度。(6<=n<=50)
输出
根据要求输出阵列,阵列的最后一行结束后也有换行。
样例输入
12
样例输出
关键代码
****
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == 1 || i == n || j == 1 || j == n)
cout << "*";
else if (i == n / 2 || i == n / 2 + 1 || j == n / 2 || j == n / 2 + 1)
cout << "+";
else if (i<n / 2 && j>n / 2 + 1)
cout << 1;
else if (i < n / 2 && j < n / 2)
cout << 2;
else if (i > n / 2 + 1 && j < n / 2)
cout << 3;
else if (i > n / 2 + 1 && j > n / 2 + 1)
cout << 4;
}
cout << endl;
}
注意事项
通过规律可以看出 第一行、最后一行、第一列、最后一列输出星号,中间两行和中间两列输出加号,然后根据分开的四个位置分别输出四个象限。
二、简易算24点
描述
有4个正整数,要求在不改变数字顺序、不添加括号的前提之下,在每两个数字之间添加一个加法+或者乘法*运算符,凑成一个完整的运算表达式,使得表达式的运算结果为24。
已知这4个正整数,问可以凑出多少种不同的满足要求的表达式?
输入
多组案例。一个正整数n,表示案例的数量。(n<=200000)
每组案例由4个不大于20的正整数组成。
输出
针对每组案例,输出一个整数,表示有多少种不同的满足条件的表达式。
每组案例输出完都要换行。
样例输入
3
2 2 2 3
2 2 2 2
1 2 3 18
样例输出
1
0
2
关键代码
********
if(a+b+c+d==24)
cnt++;
if(a+b+c*d==24)
cnt++;
if(a+b*c+d==24)
cnt++;
if(a*b+c+d==24)
cnt++;
if(a+b*c*d==24)
cnt++;
if(a*b*c+d==24)
cnt++;
if(a*b+c*d==24)
cnt++;
if(a*b*c*d==24)
cnt++;
********
注意事项
八个可能,暴力就完事。
三、带分数
描述
以一个假分数的形式,输入一个分数的分子和分母部分,要求输出为带分数形式,并且应当正确约分。
例如输入10 8,应输出1+1/4,因为10/8=1+1/4。
如果带分数的整数部分为0,那么只要输出其分数部分。
例如输入2 8,应输出1/4,因为2/8=1/4。
如果带分数的分数部分为0,那么只要输出其整数部分。
例如输入16 8,应输出2,因为16/8=2。
输入
多组案例。一个正整数n,表示案例的数量。(n<=100)
每组案例由两个正整数a和b组成,表示分数的分子和分母。(均不大于1e+8)
输出
针对每组案例,输出带分数形式的分数,具体要求见【问题描述】。
每组案例输出完要换行。
样例输入
3
10 8
2 8
16 8
样例输出
1+1/4
1/4
2
关键代码
*********
int gcd(int a, int b)//最大公约数(辗转相除法)
{
return b > 0 ? gcd(b, a % b) : a;
}
********
int c = a / b;
a = a - c * b;
if (a == 0)
cout << c << endl;
else
{
int x = gcd(a, b);
a = a / x, b = b / x;
if (c == 0)
cout << a << "/" << b << endl;
else
cout << c << "+" << a << '/' << b << endl;
}
注意事项
化为最简分数需要用到寻找最大公约数的函数,c是带分数的整数部分,然后a和b就变成了一个真分数,a,b可能不是最简分数,所以寻找a,b的最大公约数,a,b同时除最大公约数就是最简分数。
四、直线关系
描述
已知平面直角坐标系的两条直线ax+by+c=0,dx+ey+f=0,问这两条直线的关系是重合、平行还是相交?
输入
多组案例。一个正整数n,表示案例的数量。(n<=100)
每组案例由6个整数a、b、c、d、e、f组成(绝对值均不大于10000)
输出
针对每组案例,如果两直线重合,则输出1;如果两直线平行,则输出2;如果两直线相交,则输出3。
每组案例输出完要换行。
样例输入
2
1 2 3 4 5 6
1 1 1 1 1 1
样例输出
3
1
关键代码
********
int D = a1 * b2 - b1 * a2;
int Dx = (-c1) * b2 - b1 * (-c2);
int Dy = a1 * (-c2) - (-c1) * a2;
if (D != 0)
cout << 3 << endl;
else
{
if (Dx != 0 || Dy != 0)
cout << 2 << endl;
else if (Dx == 0 & Dy == 0)
cout << 1 << endl;
}
注意事项
通过行列式求解
通过高中的一般式和斜截式的方法判断直线关系都有缺陷
五、覆盖范围
描述
已知一个无穷数列的首项是a,从第二项开始,每项是前一项乘b加c后,除以d的余数。问这个数列能够生成多少个不同的数字。
输入
多组案例。一个正整数n,表示案例的数量。(n<=100)
每组案例由4个正整数a、b、c、d组成。(均不大于10000)
输出
针对每组案例,输出一个整数,表示这个无穷数列能生成不同数字的个数。
每组案例输出完要换行。
样例输入
2
1 1 1 10
1 1 2 10
样例输出
10
5
关键代码
*******
int sz[10001] = { 0 };
int x = a;
sz[a]++;
while (1)
{
x = (x * b + c) % d;
sz[x]++;
if (sz[x] > 1)
break;
}
int ans = 0;
for (int i = 0; i < 10001; i++)
{
if (sz[i] > 0)
{
ans++;
}
}
*************
注意事项
sz数组是用来储存出现过的数字,由题意可知 最后的数列一定是周期数列所以一有一个数重复出现,就表明进入了下一个周期,就能判断一共出现了多少个不一样的数字。
六、哪类更多
描述
将正整数根据其因子的数量分类,例如18有1、2、3、6、9、18这6个因子,那么称18为“6类整数”。
把所有a~b之间的整数(含a和b)按照以上原则分类,问哪类整数的数量最多?有多少个?
输入
多组案例。一个正整数n,表示案例的数量。(n<=20)
每组案例由两个正整数a和b组成。(1<=a<=b<=1e+7)
输出
针对每组案例,输出两个整数x和y,其中x表示数量最多的是x类整数,y表示该类整数的数量。
如果遇到多类整数并列最多,则输出其中最小的x值。
x和y之间要有一个空格。
每组案例输出完要换行
样例输入
2
6 8
4 5
样例输出
4 2
2 1
关键代码
*********
for (int i = 1; i < 1e+7; i++)
{
for (int j = i; j <= 1e+7; j += i)
{
factorCnt[j]++;
}
}
int n;
cin >> n;
while (n--)
{
int type[450] = { 0 };
int a, b;
cin >> a >> b;
int Max = -1, pos;
for (int i = a; i <= b; i++)
{
type[factorCnt[i]]++;
if (type[factorCnt[i]] > Max)
{
Max = type[factorCnt[i]];
pos = factorCnt[i];
}
else if (type[factorCnt[i]] == Max && factorCnt[i] < pos)
pos = factorCnt[i];
}
}
**************
注意事项
用传统方法找因数肯定会超时,所以要用筛的方法,例如1 是所有数的因数 ,factorCnt的所有数加一,2是所有偶数的因数 factorCnt[偶数]加一……以此类推。(实测运行时间为1500ms差不多)
然后就是Type数组是储存factorCnt[i]类整数的个数,实测最大的因数个数是448 数字是8648640(可能还有别的数字也有这么多因数),所以type数组只要开449(强迫症患者开了450)就行。
然后就是寻找数量最多的n类整数和整数个数,要注意如果遇到多类整数并列最多,则输出其中最小的x值。