C算法题

1 篇文章 0 订阅

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,然后每次循环比较大小求最小的序列号,大小相等则判定字典序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值