算法入门(2)

算法入门

最近一直在学习算法,因此看了算法竞赛入门经典这本书,因此把这本书的很多习题和讲解都自己做了一下,感觉对自己帮助非常大,由于工作量非常大,并不是几天就能写完的,所以我打算每天都花一些时间来写写上面的代码,并且把自己所写的记录下来,本部分内容会持续更新。。。

今天所做的一些题如下,对大家应该非常有帮助吧!

蛇形填数
在nxn方阵里填入1,2,……,nxn,要求填成蛇形。例如,n=4时方阵为
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
之前在一次校园招聘中遇到了蛇形填数这道题,当时由于时间很紧,就写了一些,现在重新做到这道题,理解相当深刻了。以后遇到这类题的时候,只要套用这个模板就可以做出来了。

#include <stdio.h>
#include <iostream>
using namespace std;
#define maxn 20
int a[maxn][maxn];
int main(){
      int n, x, y, tot = 0;
      scanf("%d", &n);
      memset(a, 0, sizeof(a));
      tot = a[x = 0][y = n - 1] = 1;
      while (tot<n*n)
      {
            while (x + 1 < n && !a[x + 1][y]) a[++x][y] = ++tot;
            while (y - 1 >= 0 && !a[x][y-1]) a[x][--y] = ++tot;
            while (x - 1 >= 0 && !a[x-1][y]) a[--x][y] = ++tot;
            while (y + 1 < n && !a[x][y+1]) a[x][++y] = ++tot;
      }
      for (int i = 0; i < n; i++)
      {
            for (int j = 0; j < n; j++){
                  printf("%3d", a[i][j]);
            }
            printf("\n");
      }
      system("pause");
      return 0;
}

Tex中的引号
在Tex中,左引号是”",右引号是“‘’”。输入一篇包含双引号的文章,任务是把它转换成Tex的格式
样例输入:
“ to be or not to be”
输出:
to be or not to be’
我们有时候会遇到这类题,对字符串的处理,本例值得参考

#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
     int c, q = 1;
     while ((c = getchar())!=EOF)  //读取字符
     {
           if (c == '"')
           {
                printf("%s", q ? "``" : "''");
                q = !q;  //控制输出`` 还是''
           }
           else
           {
                printf("%c", c);
           }
     }
     system("pause");
     return 0;
}

把手放在键盘上,稍不注意就会往右错一位。这样,输入Q会变成W,输入J会变成输入K等。输入一个错位后敲出的字符串(所有字母均大写),输出打字员想打出的句子。输入保证合法,一定是错位之后的字符串。例如输入中不会出现大写字母A。
样例输入:O S, GOMR YPFSU/
输出:I AM FINE TODAY.

#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
     char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'\ZXCVBNM,./";  //字符串保存键盘上的大写字母
     int c;
     int i;
     while ((c =getchar())!=EOF)  
     {
           for (i = 1; i < strlen(s); i++){  //遍历寻找
                if (s[i]==c)
                {
                     break;  //找到退出循环
                }
           }
           if (s[i])
           {
                printf("%c", s[i - 1]);
           }
           else
                printf("%c", c);

     }
     system("pause");
     return 0;
}

回文串
输入一个字符串,判断它是否为回文串,例如abba
回文串是在公司笔试题中经常遇到的问题,我在这里简单的写了一个例子,虽然简单,但是应该帮助挺大。

#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
     char s[30];
     while (scanf("%s",s)==1)
     {
           int len = strlen(s);
           int mid = (len + 1) / 2;
           int p=1;
           for (int i = 0; i < len; i++)
           {
                if (s[i] != s[len - 1 - i])
                     p = 0;
           }
           if (p) printf("a regular palindreome");
           else
                printf("not a alindrome");
     }
     system("pause");
     return 0;
}

猜数字游戏的提示
实现一个经典”猜数字”游戏。给定答案序列和用户猜的序列,统计有多少数字位置正确 (A),有多少数字在两个序列都出现过但位置不对(B)。
输入包含多组数据。每组输入第一行为序列长度n,第二行是答案序列,接下来是若干 猜测序列。猜测序列全0时该组数据结束。n=0时输入结束。

#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
     const int maxn = 1020;
     int a[maxn],b[maxn],n;
     int kcase = 0;
     while (scanf("%d",&n)==1 && n)  //输入数字数目,当为0时结束游戏
     {
           printf("Game %d\n", ++kcase);
           for (int i = 0; i < n; i++)
           {
                scanf("%d", &a[i]); //输入答案序列
           }
           for (;;)
           {
                int A = 0;
                int B = 0;
                for (int i = 0; i < n; i++){
                     scanf("%d", &b[i]);  //输入猜测序列
                     if (a[i] == b[i])
                     {
                           A++; //正确位置
                     }
                }
                if (b[0] == 0)
                {
                     break;
                     break;  //当猜测序列第一个为0时,退出游戏
                }
                for (int d = 1; d < 9; d++)
                {
                     int c1 = 0, c2 = 0;
                     for (int i = 0; i < n; i++)
                     {
                           if (a[i] == d)
                           {
                                c1++;
                           }
                           if (b[i] == d)
                           {
                                c2++;
                           }
                     }
                     if (c1 < c2)
                     {
                           B += c1;
                     }
                     else
                           B += c2;
                }
                printf("(%d,%d)\n", A, B - A);
           }
     }
     system("pause");
     return 0;
}

环状序列
长度为n的环状串有n种表示法,分别为从某 个位置开始顺时针得到。例如,下图的环状串 有10种表示:这里写图片描述

CGAGTCAGCT,GAGTCAGCTC,AGTCAGCTCG等。在这些表示法中,字典序最小的称 为”最小表示”。

#include <stdio.h>
#include <iostream>
using namespace std;
int compare(const char *s, int p, int q);
int main(){
     const int maxn = 1024;
     char s[maxn];
     int n;
     scanf("%d", &n);
     for (int i = 0; i < n; i++)
     {
           scanf("%s", s);
           int ans = 0; //最终得到的位置
           int len = strlen(s);
           for (int j = 0; j < len; j++)
           {
                if (compare(s, j, ans)) ans = j;
           }
           for (int m = 0; m < len; m++)
           {
                putchar(s[(ans + m) % len]);
           }
     }
     system("pause");
     return 0;
}

int compare(const char *s, int p, int q){ //比较字符串p和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;
}

好了,本篇文章写了几个小程序,读者遇到类似问题都可以直接copy代码在vs中运行,作为一名刚开始写博客的小白来说,水平一般,望大家谅解,我会继续努力的,敬请期待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值