输入形式:输入一个数n,代表有多少组DNA分子。再输入两个数分别为a和b,代表一段DNA分子所占用的行数和一段DNA的重复度。下文加叹号的位置很重要。
!!!我使用的编译器是vs2022,scanf写成scanf_s,若是dev c++编译器,还是scanf。
示例:
如图,2表示两个组DNA,3 3表示一小段DNA占三行,重复该小段DNA三次。5 2同理。
要打印图形需要用到二维字符型数组。
c[i][j]为一个二维数组,将他定义为字符形式的数组。既然是二维就可以将数组里面的字符平铺进一个平面里。
如图c[5][5]的字符型数组,要让它主对角线(黑色)和副对角线(红色)位置都打印X,其他位置打印空格,就能实现一小段DNA的打印。
!!!接下来就只需要求主副对角线和i,j之间的关系了。(将i视为x,j视为y。放在直角坐标系中求方程可以求出) 主对角线:i=j ; 副对角线:j=a+1-i;(a为你所定义的一小段DNA的行数,就比如上方示例中5 2中的5)(求到这里问题就要解决了。)
仔细观察发现,第一小段DNA下面的若干小段DNA都是去了第一行后拼接在前一小段DNA之后的。
for (i = 1; i <= a; i++)
{
for (j = 1; j <= max(i, a + 1 - i); j++)
//对于j<=max(i,a+1-i)是想要在打印完该行的最后一个X后结束该行的打印
{
if (i == j || j == a + 1 - i) printf("X");//到主对角线或副对角线时打印X。
else printf(" ");
}
printf("\n");//打印完一行了,要换下一行。
}
!!!上述代码就是第一小段DNA的打印步骤(i代表行,j代表列)(核心代码)
打印完第一小段DNA之后该打印之后的每小段DNA了。
for (m = 1; m < b; m++)//b表示有多少小段DNA分子,m循环了b-1次,b-1次是因为第一小段DNA打印过了。
for (i = 2; i <= a; i++)//与上篇代码不同之处就是i初始值变成了2。表示不打印第一行了。
{
for (j = 1; j <= max(i, a + 1 - i); j++)
{
if (i == j || j == a + 1 - i) printf("X");
else printf(" ");
}
printf("\n");
}
到这里就可以打印一个完整的DNA分子了。
接下来输入一个数n,for(k=1;k<=n;k++)在此for循环中加入scanf函数输入两个数到a[k] b[k]之中。这就实现了开头的输入形式。
接下来就是全部代码了:
#include<stdio.h>
int main()
{
int a[10], b[10], i, j, k, n, m;
char c[100][100];
scanf_s("%d", &n);
for (k = 1; k <= n; k++)
scanf_s("%d%d", &a[k], &b[k]);
int max(int x, int y);
for (k = 1; k <= n; k++)
{
for (i = 1; i <= a[k]; i++)
{
for (j = 1; j <= max(i, a[k] + 1 - i); j++)
{
if (i == j || j == a[k] + 1 - i) printf("X");
else printf(" ");
}
printf("\n");
}//到这里第一小段DNA打印完毕。
for (m = 1; m < b[k]; m++)
for (i = 2; i <= a[k]; i++)
{
for (j = 1; j <= max(i, a[k] + 1 - i); j++)
{
if (i == j || j == a[k] + 1 - i) printf("X");
else printf(" ");
}
printf("\n");
}//到这里第一小段DNA之后的DNA打印完毕。
printf("\n");//两个DNA分子之间要空一行。
}
}
int max(int x, int y)
{
int t;
if (x > y) t = x;
else t = y;
return t;
}