1.循环结构程序设计
1.1题目:输出所有形如AABB的四位完全平方数,如:7744
分析:简单
public static void main(String [] args){
for(int i = 1; i<10; i ++){
for(int j = 0; j <10; j ++){
int n = i * 1100 + j * 11;
int m =(int)(Math.sqrt(n)+0.5);
if(m * m == n)
{
System.out.println(n);
}
}}}
解析:拿出这个简单的案例,是为了警醒我们误差的存在,即1变成0.9999999的问题,所以红色的代码为了避免这样的情况,做了特殊处理。
1.2题目:相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排,五人一排,七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入3个非负整数a,b,c,表示每种队形排尾的人数(a <3,b <5,c <7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100。
输入2 1 6输出41。
分析:注意限制条件
void main(){
int a,b,c;
scanf(“%d%d%d”,&a,&b,&c);
int i,f = 0;
for(i = 10; i<= 100; i ++)
{
if(i%3 == a && i%5 == b && i%7 == c)
{
printf(“%d \ n”,i);
f = 1;
}
}
char s[] =“no answer”;
if(i == 101 && f == 0){
printf(“%s”,s);
}
}
解析:如果把i <= 100改为i <= 1000,这个代码就存在问题,所以在f = 1;后加break;
1.3题目:从1-9中取不重复数字满足形如abc:def:ghi = 1:2:3,输出所有abc def ghi。举例:219 438 657。
分析:9个循环判定即可,但这里采用另一个方法
void main(){
for(int i = 1; i<10; i ++){
for(int j = 1; j <10; j ++){
for(int k = 1; k <10; k ++){
if((i!= j)&&(j!= k)&&(i!= k)){
int sum = i * 100 + j * 10 + k;
int sum2 = sum * 2;
int sum3 = sum * 3;
if(sum * 3 <1000){
int aa [9];
aa [0] = sum2 / 100; aa [1] = sum2 / 10%10; aa [2] = sum2%10; aa [3] = sum3 / 100;
aa [4] = sum3 / 10%10; aa [5] = sum3%10; aa [6] = i; aa [7] = j; aa [8] = k;
int flag = 0;
for(int l = 0; l <9; l ++)
{
for(int m = l + 1; m <10; m ++)
{
if(aa [l] == aa [m])
{
flag = 0;
break;
}
else {
flag = 1;
}
}
if(flag== 0)
{
break;
}
}
if(flag== 1)
{
printf(“%d%d%d \ n”,sum,sum2,sum3);
}
}}}}}}
解析:先找出最小的ABC,他的值* 3为ghi自然要小于1000,然后对abc,def,gif的每个数字存入数组比较,这里用的方法是稍改了冒泡排序的结构,最后输出不重复的值。
1.4蛇形输出一组N * N的数,如:
4 1
3 2
分析:用二维数组,设定好为1的值后开始循环存入数据,数组移动顺序为下,左,上,右给出如果条件进行判断。
public static void main(String [] args){
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int aa [] [] = new int [n] [n];
int sum = 1;
int x = 0,y = n-1;
aa [x] [y] =sum;
while(sum <n * n){
while(x + 1 <n && aa [x + 1] [y] == 0){
aa [++ x] [y] = ++ sum;
}
while(y> 0 && aa [x] [y-1] == 0){
aa [x] [ - y] = ++ sum;
}
while(x> 0 && aa [x-1] [y] == 0){
aa [ - x] [y] = ++ sum;
}
while(y + 1 <n && aa [x] [y + 1] == 0){
aa [x] [++ y] = ++ sum;
for(int i = 0; i <n; i ++){
for(int j = 0; j <n; j ++){
System.out.print(aa [i] [j] +“\ t”);
}
System.out.println();
}
}
解析:主要是while循环条件的灵活使用。
2.字符串与数组
2.1输入一段字符串,如果将它首尾围成一个圈后,输出它最小的字典序排列,如dcbada,输出:adadcb
分析:想办法找到最小的字典序数组序号,并以此作为起点输出。
int less(const char* s, int p, int q) {
int n = strlen(s);
for (int i = 0; i < n; i++) {
if (s[(p + i) % n] != s[(q + i) % n]) {
return s[(p + i) % n] < s[(q + i) % n];
}
}
return 0; // 相等
}int main() {
char s[maxn];
scanf("%s", s);
int ans = 0;
int n = strlen(s);
for (int i = 1; i < n; i++) {
if (less(s, i, ans)) ans = i;
}
for (int i = 0; i < n; i++) {
putchar(s[(i + ans) % n]);
}
putchar('\n');
system("pause");
return 0;
}
解析:用%符号来循环数组,用less()比较i与i + 1的的大小,取较小的序号作为起点红色部分可看作稍改动的冒泡结构。
2.2输入字符串,求最小重复周期数k,如abcabcabc,k = 3,abab,k = 2
分析:同是循环判定字符是否相等,答案方法却更巧妙,我是用的查找判定字符串周期的方法,答案是依次从1开始增大周期判定是否满足。
int main(){
int N;
char str[100];
scanf("%d", &N);
scanf("%s", str);
int len = strlen(str);
for (int step = 1; step <= len; ++step) {
if (len % step == 0) {
bool flag = true;
for (int i = step; i < len; ++i) {
if (str[i] != str[i % step]) {
flag = false;
break;
}
}
if (flag) {
printf("%d\n", step);
if (N > 0) printf("\n");
break;
}
}}}
解析:红1可以直接否决奇序列无偶周期情况,step就是慢慢增大的周期,红2是对步骤是否满足条件判断。
2.2 有5*5的方格,其中一个为空,其他格子有一个字母,有A,B,L,R四个指令分别代表上下左右。
输出的初始的网格,输入指令,输出执行完后的网格,非法指令输出no anwer。
分析:直接用一维数组存入25个值,并使其中一个为空,向上就下标-5嘛。参考答案用了指针和结构体,还写了80行,不建议看,贴出我的简单实现代码。
int main(){
int n, flag = 0, k = 12;
char aa[25];
char bb[10];
for (int i = 0;i < 25;i++)
{
aa[i] = char(i+97);
}
aa[k] = ' ';
for (int i = 0;i < 25;i++)
{
if (i%5==0&&i!=0)
{
printf("\n");
}
printf("%c ", aa[i]);
}
printf("\n");
scanf("%s", bb);
n = strlen(bb);
for (int i = 0;i < n;i++)
{
if (bb[i] == 'A'&&(k - 5>=0))
{
k = k - 5;
aa[k + 5] = aa[k];
aa[k] = ' ';
}
else if (bb[i] == 'B'&&(k + 5<25))
{
k = k + 5;
aa[k - 5] = aa[k];
aa[k] = ' ';
}
else if (bb[i] == 'R'&&(k + 1<25))
{
k = k + 1;
aa[k - 1] = aa[k];
aa[k] = ' ';
}
else if (bb[i] == 'L'&&(k - 1>=0))
{
k = k - 1;
aa[k + 1] = aa[k];
aa[k] = ' ';
}
else {
flag = 1;
break;
}
}
if (flag == 1)
{
printf("no anwer");
}
else {
for (int i = 0;i < 25;i++)
{
if (i % 5 == 0 && i != 0)
{
printf("\n");
}
printf("%c ", aa[i]);
}
}}
解析:无。
2.3 输入m和n,输入m个长度为n的DNA(只能有A,T,C,G)序列,求一个序列,它与其他的不相同个数最低,如果有多解,算字典序最小的那个。
分析:循环比较,由于用的二维数组存,所以应该用3个for循环,找出最小的序列号。
int main(){
int i, n, m, j = 0, k = 0, min = 1000, s = 0, l = 0;
scanf("%d%d", &m, &n);
char aa[100][100];
char bb[100];
for (i = 0;i < m;i++)
{
scanf("%s", aa[i]);
}
for (i = 0;i < m;i++)
{
s = 0;
for (j = 0;j < m;j++)
{
for (k = 0;k < n;k++)
{
if (aa[i][k] != aa[j][k])
{
s++;
}
}
}
if (min!=1000&&min > s)
{
min = s;
strcpy(bb, aa[i]);
}
else if (min != 1000 && min == s) {
min = s;
for (l=0;l<n;l++)
{
if (bb[l]>aa[i][l])
{
strcpy(bb, aa[i]);
break;
}
}
}
else if (min == 1000 ) {
min = s;
strcpy(bb, aa[i]);
}
}
printf("%s", bb);
}
解析:利用s计数每行序列所有的不同的个数,所以比较序号都可以从0开始,一开始直接存入第一个s,然后每次循环比较大小求最小的序列号,大小相等则判定字典序。