第03章_数组和字符串

03_数组和字符串

Example_0301_逆序输出_数组.cpp

Example_0302_开灯问题.cpp

Example_0303_蛇形填数.cpp

Example_0304_竖式问题.cpp

Example_0305_最长回文子串_预处理方法.cpp

Exercise_0301_分数统计(stat)_vector_pair.cpp

Exercise_0302_单词的长度(word)_string.cpp

Exercise_0303_乘积的末3(product)_cctype.cpp

Exercise_0304_计算器(calculator)_simple.cpp

Exercise_0305_方阵旋转(rotate).cpp

Exercise_0306_进制转换1(base1)_十进制转x进制.cpp

Exercise_0307_进制转换2(base2)_x进制转十进制.cpp

Exercise_0308_手机键盘(keyboard).cpp

 

  1. // Example_0301_逆序输出_数组.cpp  
  2.   
  3. /** 
  4.  * 题目名称:逆序输出 
  5.  * 题目描述:将数组内的数逆序输出。 
  6.  **/  
  7.   
  8. #include <stdio.h>  
  9. #define MAXN 100 + 10  
  10.                        // 为保险起见,这里将数组的最大值声明得稍大一些  
  11. int a[MAXN];           // 比较大的数组应尽量声明在main函数外  
  12.                        // 附: 全局变量在静态存储区分配内存  
  13.                        //      局部变量在栈上分配内存空间  
  14.   
  15. int main()  
  16. {  
  17.     int i, x, n = 0;  
  18.     while(scanf("%d", &x) == 1){  
  19.         a[n++] = x;  
  20.     }  
  21.     for (i = n - 1; i >= 1; i--){  
  22.         printf("%d ", a[i]);  
  23.     }  
  24.     printf("%d\n", a[0]);  
  25.     return 0;  
  26. }  


 

  1. // Example_0302_开灯问题.cpp  
  2.   
  3. /** 
  4.  * 题目名称:开灯问题 
  5.  * 题目描述: 
  6.  *      有n盏灯,编号为1~n。第1个人把所有灯打开,第2个人按下所有编号为2的总数的开关(这些灯将补关掉), 
  7.  * 第3个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关掉),依此类推。 
  8.  * 一共有k个人,问最后有哪此灯开着?输入n和k,输出开着的灯的编号。 k <= n <= 1000. 
  9.  * 样例输入: 7 7 
  10.  * 样例输出: 1 5 6 7 
  11.  **/  
  12.   
  13. /** 
  14.  * 题目分析: 
  15.  *     这题并不难,只需要使用两个循环即可实现。 
  16.  * 首先,我们可以先去理解一下开关灯实际上是什么,可以知道,开关灯,实际上是一种状态。 
  17.  * 那么,我们可以使用一个数值来代表这种状态,下面的程序,用数值1表示开灯,数值0表示关灯。 
  18.  * 由于这里有1 ~ n 盏灯,我们可以用一个数组来存放这n盏灯的信息。 
  19.  * 解决开关灯状态问题后,可以开始算法思路: 
  20.  * 题目中,要求第n个人就会将编号为n的倍数的灯的状态值改变,那么,我们可以在一个循环中负责实现“人”的改变。 
  21.  * 然后,再在这个“人”的改变的循环中再嵌入一个处理”灯“的状态改变的函数。 
  22.  **/  
  23.   
  24. #include <stdio.h>  
  25. #include <string.h>  
  26. #define MAXN 1000 + 10  
  27. int a[MAXN];  
  28.   
  29. int main()  
  30. {  
  31.     int i, j, n, k, first = 1;  
  32.     memset(a, 0, sizeof(a));  
  33.     scanf("%d%d", &n, &k);  
  34.     for (i = 1; i <= k; i++){  
  35.         for (j = 1; j <= n; j++){  
  36.             if(j % i == 0){     // 无余数时是倍数关系,灯的状态得做出对应的变化  
  37.                 a[j] = !a[j];  
  38.             }  
  39.         }  
  40.     }  
  41.     for ( i = i; i <= n; i++){  
  42.         if(a[i]){  
  43.             if (first){  
  44.                 first  = 0;  
  45.             }  
  46.             else{  
  47.                 printf(" ");  
  48.             }  
  49.             printf("%d", i);  
  50.         }  
  51.     }  
  52.     printf("\n");  
  53.     return 0;  
  54. }  


 

  1. // Example_0303_蛇形填数.cpp  
  2.   
  3. /** 
  4.  * 题目名称:蛇形填数 
  5.  * 题目描述:在n*n方阵里填入1, 2, ..., n*n, (n <=8)要求填成蛇形(多余的空格只是为了便于观察规律,不必严格输出)。 
  6.  * 样例输入: 4 
  7.  * 样例输出: 
  8.  *             10 11 12 1 
  9.  *              9 16 13 2 
  10.  *              8 15 14 3 
  11.  *              7  6  5 4 
  12.  **/  
  13.   
  14. /** 
  15.  * 题目分析: 
  16.  *     这里主要用到的是二维数组的知识,还有有点类似“迷宫”的一个判断方法。 
  17.  *     首先原题说需要n*n (n <= 8)的方阵,那么,我们只需要定义一个a[n][n]的数组即可。 
  18.  *     接下来,观察输出矩阵的蛇形规律,将数组中的每一元素初始化为0,将数字“1“从右上角开始填写, 
  19.  * 然后,一直沿着 下 -> 左 -> 上 -> 右 的方向填充数字,直到全部0都填完为止。 
  20.  * 那么,我们需要解决的问题,就只有如何能让它按这个方向走呢?我们可以将本来的0作为是否需要填充标记, 
  21.  * 再将数组的边界作为另一个是否越界的标记。总之,就是根据这些标记,沿着指定方向,填充到不能填充为止。 
  22.  * 最后,要解决的问题就是,如何知道它已经全部填充完了,然后跳出这个循环呢?我们可以用它本来需要填充的 
  23.  * 数字个数作为标记,当它的数值小于方阵的总格子个数时,即符合要求。当然,需要注意的一个问题就是,当进行 
  24.  * 确定它移动方向的判断时,需要先从数组边界作为越界条件去判断,然后再从数值上判断,这是为了防止内存溢出 
  25.  * 的情况出现。 
  26.  **/  
  27.   
  28. #include <stdio.h>  
  29. #include <string.h>  
  30. #define MAXN 10  
  31.   
  32. int a[MAXN][MAXN];  
  33.   
  34. int main()  
  35. {  
  36.     int n, x, y, tot = 0;  
  37.     scanf("%d", &n);  
  38.     memset(a, 0, sizeof(a));  
  39.     tot = a[x = 0][y = n - 1] = 1;  
  40.     while(tot < n * n){  
  41.         while(x + 1 < n && !a[x + 1][y]) a[++x][y] = ++tot;     // 下  
  42.         while(y - 1 >= 0 && !a[x][y -1]) a[x][--y] = ++tot;     // 左  
  43.         while(x - 1 >= 0 && !a[x - 1][y]) a[--x][y] = ++tot;    // 上  
  44.         while(y + 1 < n && !a[x][y + 1]) a[x][++y] = ++tot;     // 右  
  45.     }  
  46.     for (x = 0; x < n; x++){        // 行输出  
  47.         for (y = 0; y < n; y++){    // 列输出  
  48.             printf("%3d", a[x][y]);  
  49.         }  
  50.         printf("\n");  
  51.     }  
  52.     return 0;  
  53. }  


 

  1. // Example_0304_竖式问题.cpp  
  2.   
  3. /** 
  4.  * 题目名称:竖式问题 
  5.  * 题目描述: 
  6.  *      找出所有形如abc*de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合。 
  7.  * 输入数字集合(相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一行空行。最后输出解的总数。 
  8.  * (为了便于观察,竖式中的空格改用小数点显示,但你的程序应该输出空格,而非小数点)。 
  9.  * 样例输入: 2357 
  10.  * 样例输出: 
  11.  * <1> 
  12.  * ..775 
  13.  * X..33 
  14.  * ----- 
  15.  * .2325 
  16.  * 2325. 
  17.  * ----- 
  18.  * 25575 
  19.  * 
  20.  * The number of solutions = 1 
  21.  **/  
  22.   
  23.  /** 
  24.   * 题目分析: 
  25.   * 尝试所有的abc和de,判断是否满足条件 if (" abc *de")是个合法的竖式)打印abc*de的竖式和其后的空行。 
  26.   * 其实主要还是要找出主要需要解决的条件,在这题里面,需要解决的问题主要有两个。 
  27.   * 第一个:输出格式控制,这个主要对cout或者prinf的使用方法熟悉即可, 
  28.   * 第二个:“所有数字都属于一个特定的数字集合”,这里需要掌握筛选数字的技巧,下例中使用了“缓冲区”的方法。 
  29.   *          首先,申请两个字符数组,第一个字符数组用于存放用户输入的字符,第二个字符数组用于存放进行乘法时出现过的数字的保存。 
  30.   *          开始执行的过程, 
  31.   *          第一步,将用户输入数字集合放到s字符组中。 
  32.   *          第二步,计算,然后将计算时所有出现过的数字存放到另一个字符数组buf中。 
  33.   *          第三步,开始逐个比较,判断是否buf中每个字符都能从s字符组中找到,起到了最终的筛选作用。 
  34.   **/  
  35.   
  36.   #include <stdio.h>  
  37.   #include <string.h>  
  38.   
  39.   int main()  
  40.   {  
  41.       int i, ok, abc, de, x, y, z, count = 0;  
  42.       char s[20], buf[99];  
  43.       scanf("%s", s);           // 要求用户输入数字集合,并将数字集合放入到字符组s[20]中。  
  44.       for (abc = 111; abc <= 999; abc++){ // 这两个循环是为了列举所有的两位数和三位数的数字集合  
  45.           for (de = 11; de < 99; de++){  
  46.               x = abc * (de % 10);  
  47.               y = abc * (de / 10);  
  48.               z = abc * de;  
  49.               sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z); // 将计算结果得出的数字全部放入到buf字符组中  
  50.               ok = 1;  
  51.               for(i = 0; i < strlen(buf); i++){  
  52.                   if (strchr(s, buf[i]) == NULL){  // 测试buf字符组中的每一个字符是否都能从s字符组中找出  
  53.                       ok = 0;  
  54.                   }  
  55.               }  
  56.               if(ok){  
  57.                   printf("<%d>\n", ++count);  
  58.                   printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n", abc, de, x, y, z);  
  59.               }  
  60.           }  
  61.       }  
  62.       printf("The number of solutions = %d\n", count);  
  63.       return 0;  
  64.   }  
  65.   
  66. // 补充: #include <stdio.h>  int sprintf( char *buffer, const char *format, ... );  
  67. // sprintf()函数和printf()类似, 只是把输出发送到buffer(缓冲区)中.返回值是写入的字符数量.  
  68.   
  69. // 补充: #include <string.h>  char *strchr( const char *str, int ch );  
  70. // 功能:函数返回一个指向str 中ch 首次出现的位置,当没有在str 中找ch到返回NULL。  
  71. // 在C++里面可以用#include <cstring>  size_type find( char ch, size_type index );  


 

  1. // Example_0305_最长回文子串_预处理方法.cpp  
  2.   
  3. /** 
  4.  * 题目名称:最长回文子串 
  5.  * 题目描述: 
  6.  *      输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串中连续出现的字符串片段。 
  7.  * 回文的含义是:正着看和倒着看相同,如abba和yyxyy。在判断时,应该忽略所有标点符号和空格, 
  8.  * 且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。输入的字符串长度 
  9.  * 不超过5000,且占据单独一行。应该输出最长的回文串,如果有多个,输出起始位置最靠左的。 
  10.  * 样例输入: Confuciuss say: Madam, I'm Adam. 
  11.  * 样例输出: Madam, I'm Adam. 
  12.  **/  
  13.   
  14.  /** 
  15.   * 温馨提示: 
  16.   * 1. 使用fgetc(fin)可以从打开的文件fin中读取一个字符。 
  17.   * 2. 不同操作系统的回车换行符是不一致的。 
  18.   *     Windows是'\r'和'\n'两个字符,Linux是'\n',而MacOS是'r'. 
  19.   * 3. fgets(buf, MAXN, fin)读取完整的一行, 
  20.   *     (相当于C++里面的 istream &getline( char *buffer, streamsize num, char delim );) 
  21.   **/  
  22.   
  23.   /** 
  24.    * 题目分析: 
  25.    * 下面程序的主要思路概括: 
  26.    * 1. 预处理,提取转换所有的字符串。 
  27.    * 2. 遍历,设区间,比较,设标记。 
  28.    * 3. 得出结果,还原输出。 
  29.    * 
  30.    * 1. 关于预处理,下面通过了使用isalpha判断是否字母,如是字母则将原字符转换为小写放入新字符串。 
  31.    *    在放入时,还另外使用了一个数组p,用以保存预处理后的字符在原字符串中的位置,方便还原。 
  32.    * 2. 关于如何遍历比较,这里使用了循环变量i作为中心,然后再设一循环j,作为两边散开的点,作为比较点。 
  33.    *    如:现在由i做中心,长度区间为 j - i 至 j + 1;   那么,在比较时,就会 j - i 与 j + i 比较, 
  34.    *        j不断减小,如果到最后它们也不跳出循环,就使用max,x, y保存现在的位置,暂作为符合条件的最长子字符串。 
  35.    *    刚刚所说的是j - i 和j + i 这是在考虑子串长度为奇数的时候所使用的,它会以i为中心向两边散开, j 0 0 i 0 0 j 
  36.    *    当其为偶数的时候, 需要以i中左偏中心,然后,再向两边散开比较, 如: j - i 至j + i + 1 ,理解为: j 0 i 0 0 j 
  37.    * 3. 几个比较重要的变量 max : 保存最大子串的长度, p[m],本身下标为对应的预处理后的下标,值为原串的下标。 
  38.    **/  
  39.   
  40. #include <stdio.h>  
  41. #include <string.h>  
  42. #include <ctype.h>  
  43.   
  44. #define MAXN 5000 + 10  
  45.   
  46. char buf[MAXN], s[MAXN];  
  47. int p[MAXN];  
  48.   
  49. int main()  
  50. {  
  51.     // 初始化  
  52.     int n, m = 0, max = 0, x, y;  
  53.     int i, j;  
  54.     fgets(buf, sizeof(s), stdin);  
  55.     n = strlen(buf);  
  56.   
  57.     // 预处理(字符串转换)  
  58.     for (i = 0; i < n; i++){  
  59.         if(isalpha(buf[i])){  
  60.             p[m] = i;  
  61.             s[m++] = toupper(buf[i]);  
  62.         }  
  63.     }  
  64.   
  65.     // 数据判断(判断是否回文串)  
  66.     for( i = 0; i < m; i++){  
  67.         for (j = 0; i - j >= 0 && i + j < m; j++){ // 这里是为了比较总长度为奇数的子字符串  
  68.             if (s[i - j] != s[i + j]){  
  69.                 break;  
  70.             }  
  71.             if (j * 2 + 1 > max) {  
  72.                 max = j * 2 + 1;  
  73.                 x = p[i - j];  
  74.                 y = p[i + j];  
  75.             }  
  76.         }  
  77.         for (j = 0; i - j >= 0 && i + j + 1 < m; j++){// 这里是为了比较总长度为偶数的子字符串  
  78.             if (s[i - j] != s[i + j + 1]){  
  79.                 break;  
  80.             }  
  81.             if (j * 2 + 2 > max){  
  82.                 max = j * 2 + 2;  
  83.                 x = p[i - j];  
  84.                 y = p[i + j + 1];  
  85.             }  
  86.         }  
  87.     }  
  88.   
  89.     // 结果输出  
  90.     for ( i = x; i <= y; i++){  
  91.         printf("%c", buf[i]);  
  92.     }  
  93.     printf("\n");  
  94.     return 0;  
  95. }  
  96.   
  97. /** 
  98.  * 模拟输出过程: 
  99.  * Confuciuss say: Madam, I'm Adam. 
  100.  * 
  101.  * i = 0     下面开始进行新一轮 
  102.  * 
  103.  * 第一个for: j = 0 i - j = 0 i + j = 0 m = 24 
  104.  * 第一个for的max 1 然后用x 与 y 保存 i - j与i+j的值 
  105.  * 
  106.  * 第二个for: j = 0 i - j = 0 i + j + 1 = 1 m = 24 
  107.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  108.  * 
  109.  * i = 1     下面开始进行新一轮 
  110.  * 
  111.  * 第一个for: j = 0 i - j = 1 i + j = 1 m = 24 
  112.  * 第一个for: j = 1 i - j = 0 i + j = 2 m = 24 
  113.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  114.  * 
  115.  * 第二个for: j = 0 i - j = 1 i + j + 1 = 2 m = 24 
  116.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  117.  * 
  118.  * i = 2     下面开始进行新一轮 
  119.  * 
  120.  * 第一个for: j = 0 i - j = 2 i + j = 2 m = 24 
  121.  * 第一个for: j = 1 i - j = 1 i + j = 3 m = 24 
  122.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  123.  * 
  124.  * 第二个for: j = 0 i - j = 2 i + j + 1 = 3 m = 24 
  125.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  126.  * 
  127.  * i = 3     下面开始进行新一轮 
  128.  * 
  129.  * 第一个for: j = 0 i - j = 3 i + j = 3 m = 24 
  130.  * 第一个for: j = 1 i - j = 2 i + j = 4 m = 24 
  131.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  132.  * 
  133.  * 第二个for: j = 0 i - j = 3 i + j + 1 = 4 m = 24 
  134.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  135.  * 
  136.  * i = 4     下面开始进行新一轮 
  137.  * 
  138.  * 第一个for: j = 0 i - j = 4 i + j = 4 m = 24 
  139.  * 第一个for: j = 1 i - j = 3 i + j = 5 m = 24 
  140.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  141.  * 
  142.  * 第二个for: j = 0 i - j = 4 i + j + 1 = 5 m = 24 
  143.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  144.  * 
  145.  * i = 5     下面开始进行新一轮 
  146.  * 
  147.  * 第一个for: j = 0 i - j = 5 i + j = 5 m = 24 
  148.  * 第一个for: j = 1 i - j = 4 i + j = 6 m = 24 
  149.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  150.  * 
  151.  * 第二个for: j = 0 i - j = 5 i + j + 1 = 6 m = 24 
  152.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  153.  * 
  154.  * i = 6     下面开始进行新一轮 
  155.  * 
  156.  * 第一个for: j = 0 i - j = 6 i + j = 6 m = 24 
  157.  * 第一个for: j = 1 i - j = 5 i + j = 7 m = 24 
  158.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  159.  * 
  160.  * 第二个for: j = 0 i - j = 6 i + j + 1 = 7 m = 24 
  161.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  162.  * 
  163.  * i = 7     下面开始进行新一轮 
  164.  * 
  165.  * 第一个for: j = 0 i - j = 7 i + j = 7 m = 24 
  166.  * 第一个for: j = 1 i - j = 6 i + j = 8 m = 24 
  167.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  168.  * 
  169.  * 第二个for: j = 0 i - j = 7 i + j + 1 = 8 m = 24 
  170.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  171.  * 
  172.  * i = 8     下面开始进行新一轮 
  173.  * 
  174.  * 第一个for: j = 0 i - j = 8 i + j = 8 m = 24 
  175.  * 第一个for: j = 1 i - j = 7 i + j = 9 m = 24 
  176.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  177.  * 
  178.  * 第二个for: j = 0 i - j = 8 i + j + 1 = 9 m = 24 
  179.  * 第二个for的max 2 然后用x 与 y 保存 i - j与i+j+1的值 
  180.  * 第二个for: j = 1 i - j = 7 i + j + 1 = 10 m = 24 
  181.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  182.  * 
  183.  * i = 9     下面开始进行新一轮 
  184.  * 
  185.  * 第一个for: j = 0 i - j = 9 i + j = 9 m = 24 
  186.  * 第一个for: j = 1 i - j = 8 i + j = 10 m = 24 
  187.  * 第一个for的max 3 然后用x 与 y 保存 i - j与i+j的值 
  188.  * 第一个for: j = 2 i - j = 7 i + j = 11 m = 24 
  189.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  190.  * 
  191.  * 第二个for: j = 0 i - j = 9 i + j + 1 = 10 m = 24 
  192.  * 第二个for: j = 1 i - j = 8 i + j + 1 = 11 m = 24 
  193.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  194.  * 
  195.  * i = 10     下面开始进行新一轮 
  196.  * 
  197.  * 第一个for: j = 0 i - j = 10 i + j = 10 m = 24 
  198.  * 第一个for: j = 1 i - j = 9 i + j = 11 m = 24 
  199.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  200.  * 
  201.  * 第二个for: j = 0 i - j = 10 i + j + 1 = 11 m = 24 
  202.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  203.  * 
  204.  * i = 11     下面开始进行新一轮 
  205.  * 
  206.  * 第一个for: j = 0 i - j = 11 i + j = 11 m = 24 
  207.  * 第一个for: j = 1 i - j = 10 i + j = 12 m = 24 
  208.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  209.  * 
  210.  * 第二个for: j = 0 i - j = 11 i + j + 1 = 12 m = 24 
  211.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  212.  * 
  213.  * i = 12     下面开始进行新一轮 
  214.  * 
  215.  * 第一个for: j = 0 i - j = 12 i + j = 12 m = 24 
  216.  * 第一个for: j = 1 i - j = 11 i + j = 13 m = 24 
  217.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  218.  * 
  219.  * 第二个for: j = 0 i - j = 12 i + j + 1 = 13 m = 24 
  220.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  221.  * 
  222.  * i = 13     下面开始进行新一轮 
  223.  * 
  224.  * 第一个for: j = 0 i - j = 13 i + j = 13 m = 24 
  225.  * 第一个for: j = 1 i - j = 12 i + j = 14 m = 24 
  226.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  227.  * 
  228.  * 第二个for: j = 0 i - j = 13 i + j + 1 = 14 m = 24 
  229.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  230.  * 
  231.  * i = 14     下面开始进行新一轮 
  232.  * 
  233.  * 第一个for: j = 0 i - j = 14 i + j = 14 m = 24 
  234.  * 第一个for: j = 1 i - j = 13 i + j = 15 m = 24 
  235.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  236.  * 
  237.  * 第二个for: j = 0 i - j = 14 i + j + 1 = 15 m = 24 
  238.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  239.  * 
  240.  * i = 15     下面开始进行新一轮 
  241.  * 
  242.  * 第一个for: j = 0 i - j = 15 i + j = 15 m = 24 
  243.  * 第一个for: j = 1 i - j = 14 i + j = 16 m = 24 
  244.  * 第一个for: j = 2 i - j = 13 i + j = 17 m = 24 
  245.  * 第一个for的max 5 然后用x 与 y 保存 i - j与i+j的值 
  246.  * 第一个for: j = 3 i - j = 12 i + j = 18 m = 24 
  247.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  248.  * 
  249.  * 第二个for: j = 0 i - j = 15 i + j + 1 = 16 m = 24 
  250.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  251.  * 
  252.  * i = 16     下面开始进行新一轮 
  253.  * 
  254.  * 第一个for: j = 0 i - j = 16 i + j = 16 m = 24 
  255.  * 第一个for: j = 1 i - j = 15 i + j = 17 m = 24 
  256.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  257.  * 
  258.  * 第二个for: j = 0 i - j = 16 i + j + 1 = 17 m = 24 
  259.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  260.  * 
  261.  * i = 17     下面开始进行新一轮 
  262.  * 
  263.  * 第一个for: j = 0 i - j = 17 i + j = 17 m = 24 
  264.  * 第一个for: j = 1 i - j = 16 i + j = 18 m = 24 
  265.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  266.  * 
  267.  * 第二个for: j = 0 i - j = 17 i + j + 1 = 18 m = 24 
  268.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  269.  * 
  270.  * i = 18     下面开始进行新一轮 
  271.  * 
  272.  * 第一个for: j = 0 i - j = 18 i + j = 18 m = 24 
  273.  * 第一个for: j = 1 i - j = 17 i + j = 19 m = 24 
  274.  * 第一个for: j = 2 i - j = 16 i + j = 20 m = 24 
  275.  * 第一个for: j = 3 i - j = 15 i + j = 21 m = 24 
  276.  * 第一个for的max 7 然后用x 与 y 保存 i - j与i+j的值 
  277.  * 第一个for: j = 4 i - j = 14 i + j = 22 m = 24 
  278.  * 第一个for的max 9 然后用x 与 y 保存 i - j与i+j的值 
  279.  * 第一个for: j = 5 i - j = 13 i + j = 23 m = 24 
  280.  * 第一个for的max 11 然后用x 与 y 保存 i - j与i+j的值 
  281.  * 
  282.  * 第二个for: j = 0 i - j = 18 i + j + 1 = 19 m = 24 
  283.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  284.  * 
  285.  * i = 19     下面开始进行新一轮 
  286.  * 
  287.  * 第一个for: j = 0 i - j = 19 i + j = 19 m = 24 
  288.  * 第一个for: j = 1 i - j = 18 i + j = 20 m = 24 
  289.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  290.  * 
  291.  * 第二个for: j = 0 i - j = 19 i + j + 1 = 20 m = 24 
  292.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  293.  * 
  294.  * i = 20     下面开始进行新一轮 
  295.  * 
  296.  * 第一个for: j = 0 i - j = 20 i + j = 20 m = 24 
  297.  * 第一个for: j = 1 i - j = 19 i + j = 21 m = 24 
  298.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  299.  * 
  300.  * 第二个for: j = 0 i - j = 20 i + j + 1 = 21 m = 24 
  301.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  302.  * 
  303.  * i = 21     下面开始进行新一轮 
  304.  * 
  305.  * 第一个for: j = 0 i - j = 21 i + j = 21 m = 24 
  306.  * 第一个for: j = 1 i - j = 20 i + j = 22 m = 24 
  307.  * 第一个for: j = 2 i - j = 19 i + j = 23 m = 24 
  308.  
  309.  * 第二个for: j = 0 i - j = 21 i + j + 1 = 22 m = 24 
  310.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  311.  * 
  312.  * i = 22     下面开始进行新一轮 
  313.  * 
  314.  * 第一个for: j = 0 i - j = 22 i + j = 22 m = 24 
  315.  * 第一个for: j = 1 i - j = 21 i + j = 23 m = 24 
  316.  * 第一个for比较出i-j与i+j的字符不同,break出循环。 
  317.  * 
  318.  * 第二个for: j = 0 i - j = 22 i + j + 1 = 23 m = 24 
  319.  * 第二个for比较出i-j与i+j+1的字符不同,break出循环。 
  320.  * 
  321.  * i = 23     下面开始进行新一轮 
  322.  * 
  323.  * 第一个for: j = 0 i - j = 23 i + j = 23 m = 24 
  324.  * 
  325.  * 结果: Madam, I'm Adam 
  326.  * 请按任意键继续. . . 
  327.  **/  


 

  1. // Exercise_0301_分数统计(stat)_vector_pair.cpp  
  2.   
  3. /** 
  4.  * 题目名称:分数统计(stat) 
  5.  * 题目描述: 
  6.  *      输入一些学生的分数,哪个分数出现的次数最多?如果有多个并,从小到大输出。 
  7.  * 分数均为不超过100的非负实数,但最多保留两位小数。 
  8.  * 样例输入:11 11 12 12 13 13 14 14 15 16 18 39 a 
  9.  * 样例输出:11.00 分数出现了 2 次。 
  10.  * 12.00 分数出现了 2 次。 
  11.  * 13.00 分数出现了 2 次。 
  12.  * 14.00 分数出现了 2 次。 
  13.  * 请按任意键继续. . . 
  14.  **/  
  15.   
  16. /** 
  17.  * 题目分析: 
  18.  * 
  19.  * 需要进行的操作及需要满足的条件: 
  20.  * 1. 输入不确定学生数目的分数 
  21.  * 2. 找出相同分数出现的最多次数。 
  22.  * 3. 如有重复的最多次数,将其从小到大输出。 
  23.  * 4. 输出时进行格式控制,最多保留两位小数。 
  24.  * 
  25.  * 程序主要思路: 
  26.  * 1. 初始化与输入,输入到unsignedDoubleGroup中 
  27.  * 2. 获取在double向量组中每个成员出现的次数将其放入maxNumber向量组中. 
  28.  * 3. 找出分数出现次数的最大值 
  29.  * 4. 查找拥有相同最大值的数据有哪些,并将这些全部保存入result向量组中 
  30.  * 5. 输出result向量组中的结果. 
  31.  * 
  32.  * 思路再分析: 
  33.  * 1. 为了满足条件1,我们可以直接使用一个while(cin >> double)的方式来输入保存数据,将数据保存至vector中, 
  34.  *    因为需要多次重复使用这些数据,而且不知道数据的数量,所以就选择了vector。 
  35.  * 2. 获取每个成员出现次数的方法,可以先将这个vector中的数据提取出来,然后对该数组内的数逐个比较。 
  36.  * 3. 找出一组数中哪个是最大值,可直接遍历一次向量组。 
  37.  * 4. 为了判断是否有相同最大值的数据,我们还是需要遍历一次向量组,在找出有相同的最值时,这个最值对应的 
  38.  *    向量组中的这个元素放到新建的一个result向量组中保存结果。 
  39.  * 5. 遍历输出这个result向量组的结果。 
  40.  * 
  41.  **/  
  42.   
  43. #include <iostream>  
  44. #include <vector>  
  45. #include <utility>  
  46.   
  47. using std::cin;  
  48. using std::cout;  
  49. using std::endl;  
  50. using std::ios_base;  
  51.   
  52. int main()  
  53. {  
  54.     // 1. 初始化与输入,输入到unsignedDoubleGroup中  
  55.     std::vector<double> unsignedDoubleGroup;  
  56.     double unsignedDouble = -1.0;  
  57.     while(cin >> unsignedDouble){  
  58.         unsignedDoubleGroup.push_back(unsignedDouble);  
  59.     }  
  60.     if (-1.0 == unsignedDouble){    // 当一个数值也没有输入的时候可以直接跳出该函数  
  61.         return 0;  
  62.     }  
  63.   
  64.     // 2. 获取在double向量组中每个成员出现的次数将其放入maxNumber向量组中.  
  65.     int groupLong = unsignedDoubleGroup.size();  
  66.     std::vector<int> maxNumber(groupLong, 0);    // 长度为groupLong,初值全为0的整型向量组,记录每个数字出现的次数  
  67.     for (int i = 0; i < groupLong; ++i){  
  68.         const double testInt = unsignedDoubleGroup[i];  
  69.         for (int j = 0; j < groupLong; ++j){  
  70.             if (testInt == unsignedDoubleGroup[j]){  
  71.                 maxNumber[i]++;                 // 出现次数相加  
  72.             }  
  73.         }  
  74.     }  
  75.   
  76.     // 3. 找出分数出现次数的最大值  
  77.     int maxOne = maxNumber[0];  
  78.     for ( int i = 0; i < groupLong; ++i){  
  79.         if (maxNumber[i] > maxOne){  
  80.             maxOne = maxNumber[i];  
  81.             }  
  82.     }  
  83.   
  84.     // 4. 查找拥有相同最大值的数据有哪些,并将这些全部保存入result向量组中  
  85.     std::pair<intdouble> tempPair;  
  86.     std::vector< std::pair<intdouble> > result;  
  87.     for (int i = 0; i < groupLong; ++i){  
  88.         if (maxNumber[i] == maxOne){  
  89.             bool haveSame(false);  
  90.             for ( int j = 0; j < int(result.size()); ++j){  
  91.                 if (result[j].second == unsignedDoubleGroup[i]){  
  92.                     haveSame = true;  
  93.                     break;  
  94.                 }  
  95.             }  
  96.             if (false == haveSame){  
  97.                 tempPair.first = maxOne;  
  98.                 tempPair.second = unsignedDoubleGroup[i];  
  99.                 result.push_back(tempPair);  
  100.             }  
  101.         }  
  102.     }  
  103.   
  104.     // 5. 输出result向量组中的结果  
  105.     cout.precision(2);  
  106.     cout.setf(ios_base::fixed, ios_base::floatfield);  
  107.     for (int i = 0; i < int(result.size()); ++i){  
  108.         cout << result[i].second << " 分数出现了 " << result[i].first << " 次。" << endl;  
  109.     }  
  110.   
  111.     system("pause");  
  112.     return 0;  
  113. }  


 

  1. // Exercise_0302_单词的长度(word)_string.cpp  
  2.   
  3. /** 
  4.  * 题目名称:单词的长度(word) 
  5.  * 题目描述:输入若干个单词,输出它们的平均长度。单词只包含大写字母和小写字母。 
  6.  **/  
  7.   
  8. #include <cstring>  
  9. #include <iostream>  
  10.   
  11. using namespace std;  
  12.   
  13. int main()  
  14. {  
  15.     string word;  
  16.     long sum = 0;  
  17.     long count = 0;  
  18.     while (!cin.eof() && cin >> word){  
  19.         ++count;  
  20.         sum += word.size();  
  21.     }  
  22.     cout << sum / count << endl;  
  23.     return 0;  
  24. }  


 

  1. // Exercise_0303_乘积的末3位(product)_cctype.cpp  
  2.   
  3. /** 
  4.  * 题目名称:乘积的末3位(product) 
  5.  * 题目描述: 
  6.  *      输入若干个整数(可以是正数、负数或者零),输出它们的乘积的末3位。 
  7.  * 这些整数中会混入一些由大写字母组成的字符串,你的程序中应当忽略它们。 
  8.  * 样例输入:+1 +2 + -1 -2 k 12 english 54 9876 -111 
  9.  * 样例输出:712 
  10.  **/  
  11.   
  12. /** 
  13.  * 题目分析: 
  14.  *     题目难度主要在于参差的数据类型输入。 
  15.  * 题目总思路,使用while语句逐个string作为单词输入。 
  16.  * 然后通过调用函数bool getInt(...)判断该单词是否整数,另外,再利用该函数的形参将正确的整数返回。 
  17.  * 将从函数里面得出的整数与结果相乘,乘后保留末三位整数即可。 
  18.  * 其中,关于如何实现bool getInt(string get, int & nowGet)才是难题。实现方法如下: 
  19.  * 首先,考虑不是整数的情况,1.字符串为空,返回false, 2.是字母或是仅有一个符号。 
  20.  * 除了字符串为空的情况外,我们可以开始考虑字符串不为空的情况,字符串不为空时,存在三种情况, 
  21.  * 第一种,带符号的整数,第二种,不带符号的整数,第三种,不是整数。 
  22.  * 关于这三种情况,可以使用一个if-else if- else语句来实现, 
  23.  * 第一种情况:if ('+' == get[0] || '-' == get[0])带上了符号,可以直接忽略读取第[0]位符号位,然后再 
  24.  *               从最尾位开始读取,读取3位数即可停止,当读取途中不满三位数或者碰上符号位时, 
  25.  *               立即返回。 
  26.  * 第二种情况:if('0' <= get[0] && '9' >= get[0]) 直接是数字的情况下,跟第一种情况的思路基本一致, 
  27.  *               直接从最尾位开始取个位数,次尾位取十位数,倒数第三位取百位数。 
  28.  * 第三种情况:由于不符合需要的整数的转换条件,只需要直接返回false即可. 
  29.  * 另外,如果想将字符型的数字转换成数值,只需要将原来的字符型减去'0'即可得到相对应的数值。 
  30.  **/  
  31.   
  32. #include <cstring>  
  33. #include <string>  
  34. #include <cctype>  
  35. #include <cmath>  
  36. #include <iostream>  
  37.   
  38. using namespace std;  
  39.   
  40.   
  41. bool getInt(string get, int & nowGet)  
  42. {  
  43.     int stringLong = get.length();  
  44.     if (0 == stringLong){  
  45.         return false;  
  46.     }  
  47.     nowGet = 0;  
  48.     if ('+' == get[0] || '-' == get[0]){ // 带符号的正数或负数  
  49.         if (0 == (stringLong - 1)){ // 它只包含了一个符号,则直接返回  
  50.             return false;  
  51.         }  
  52.         for (int j = 0, i = stringLong - 1; i > 0 && i >= stringLong - 3; --i, ++j){  
  53.             if ('+' == get[i] || '-' == get[i]){    // 正在循环转换的过程,这个数字不满三位数,遇上了符号,直接跳出  
  54.                 break;  
  55.             }  
  56.             nowGet += int(get[i] - '0') * (int) (pow(double(10), j));  
  57.         }  
  58.         return true;  
  59.     }  
  60.     else if('0' <= get[0] && '9' >= get[0]){ // 直接是数字的情况下  
  61.         for (int j = 0, i = stringLong - 1; i >= 0 && i >= stringLong - 3; --i, ++j){  
  62.             nowGet += int(get[i] - '0') * (int) (pow(double(10), j));  
  63.         }  
  64.         return true;  
  65.     }  
  66.     else{   // 是字母  
  67.         return false;  
  68.     }  
  69. }  
  70.   
  71. int main()  
  72. {  
  73.     string word;  
  74.     long result = 1;  
  75.     while(cin >> word){  
  76.         int temp;  
  77.         if (getInt(word, temp))  
  78.         {  
  79.             result = (result * temp) % 1000;  
  80.         }  
  81.     }  
  82.     cout << result << endl;  
  83.     return 0;  
  84. }  


 

  1. // Exercise_0304_计算器(calculator)_simple.cpp  
  2.   
  3. /** 
  4.  * 题目名称:计算器 
  5.  * 题目描述: 
  6.  *      编写程序,读入一行恰好包含一个加号、减号或乘号的表达式,输出它的值。 
  7.  * 这个运算符保证是二元运算符,且两个运算符均不超过100的非负整数。 
  8.  * 运算符和运算符可以紧挨着,也可以用一个或多个空格、TAB隔开。行首末尾均可以有空格。 
  9.  * 样例输入: 1+1 
  10.  * 样例输出: 2 
  11.  * 样例输入: 2- 5 
  12.  * 样例输出: -3 
  13.  * 样例输入: 0 *1982 
  14.  * 样例输出: 0 
  15.  **/  
  16.   
  17. #include <iostream>  
  18.   
  19. using namespace std;  
  20.   
  21. int main()  
  22. {  
  23.     int a, b;  
  24.     char oper;  
  25.     cin >> a;  
  26.     do{  
  27.         cin.get(oper);          // 这题只要灵活运用 istream &get( char &ch );  
  28.     }while(!('+' == oper || '-' == oper  || '*' == oper) );  
  29.     cin >> b;  
  30.     if('+' == oper){  
  31.         cout << a + b << endl;  
  32.     }  
  33.     else if('-' == oper){  
  34.         cout << a - b << endl;  
  35.     }  
  36.     else{  // *  
  37.         cout << a * b << endl;  
  38.     }  
  39.     return 0;  
  40. }  


 

  1. // Exercise_0305_方阵旋转(rotate).cpp  
  2.   
  3. /** 
  4.  * 题目名称:矩阵旋转(rotate) 
  5.  * 题目描述:输入一个n*n字符矩阵,把它左转90度后输出。 
  6.  * 样例输入: 
  7.  *     1     2     3     4 
  8.  *     5     6     7     8 
  9.  *     9    10    11    12 
  10.  *     13    14    15    16 
  11.  * 样例输出: 
  12.  *     4     8    12    16 
  13.  *     3     7    11    15 
  14.  *     2     6    10    14 
  15.  *     1     5     9    13 
  16.  **/  
  17.   
  18.  /** 
  19.   * 题目分析: 
  20.   *     这题其实很简单,刚刚开始我还在苦想呢,它究竟左旋时下标间有些什么规律呢? 
  21.   * 后来看着看着才发觉,原来啊,只需要将输入输出的顺序调转一下即可, 
  22.   * 输入时,按横,列坐标的方式输入;输出时,按先列后横坐标的方式逐列输出。 
  23.   * 输入时,i = 0, j = 1, 2, 3....  输出时, j = 3, i = 0, 1, 2... 
  24.   * 至于如何知道它是一个多少阶的矩阵,可以使用开方的方法求得。 
  25.   **/  
  26.   
  27. #include <queue>  
  28. #include <vector>  
  29. #include <cmath>  
  30. #include <iostream>  
  31.   
  32. using namespace std;  
  33.   
  34. int main()  
  35. {  
  36.     // 初始化,输入队列,保存元素  
  37.     queue<int> allInOne;  
  38.     int tempOne;  
  39.     while(cin >> tempOne){  
  40.         allInOne.push(tempOne);  
  41.     }  
  42.     double count = allInOne.size();  
  43.     int n = int(sqrt(count));  
  44.   
  45.     // 提取并保存元素  
  46.     vector<int> init;  
  47.     vector< vector<int> > outit;  
  48.     for (int i = 0; i < n; ++i){  
  49.         for(int j = 0; j < n; ++j){  
  50.         init.push_back(allInOne.front());  
  51.         allInOne.pop();  
  52.         }  
  53.         outit.push_back(init);  
  54.         init.clear();  
  55.     }  
  56.   
  57.     // 按一定顺序输出元素  
  58.     for (int j = n - 1; j >= 0; --j){  
  59.         for (int i = 0; i < n; ++i){  
  60.             cout << outit[i][j] << " ";  
  61.         }  
  62.         cout << endl;  
  63.     }  
  64.     return 0;  
  65. }  


 

  1. // Exercise_0306_进制转换1(base1)_十进制转x进制.cpp  
  2.   
  3. /** 
  4.  * 题目名称:进制转换(base1) 
  5.  * 题目描述:输入基数b(2 <= b <= 10)和正整数n(十进制),输出n的b进制表示。 
  6.  **/  
  7.   
  8.  /** 
  9.   * 题目分析: 
  10.   * 1. 用户输入十进制数值n,基数b。 
  11.   * 2. 要求,转换为由基数b的数字。 
  12.   * 3. 这里,可以将这最终结果的数字拆分出来,将一个数字,变为一位数就一个数字,最后遍历输出。 
  13.   * 4. 假设输入数值为10,基数为3,结果应为201,我们可以试试用加法的思想去想如何转化。 
  14.   * 5. 就像以前使用的算盘那样,数值每增大1,就在个位数上加1,当个位数上的1达到基数大小时,需要进位。 
  15.   * 6. 进位以后,需要将原数位清零,这较高位加1,然后,再继续判断这较高位是否可以进位,如此循环。 
  16.   * 7. 那么,意思是: ++数值 -> 最代位(原数位)++ -> 判断是否达到基数大小 -> 原数位清零 -> 较高位++... 
  17.   * 8. 可以看出,除了第一步的操作外,下面的操作已经开始进入循环体了,也就是说,我们需要解决的第一个问题是: 
  18.   *    确定要加多少次数值。 这里,只需要将用户输入的数值n做这样的操作即可:while(n--){} 
  19.   *    在上面的循环体中,该放些什么呢?循环体中,已经开始数值相加了,也就是说,需要先初始化一个带个位数的东西, 
  20.   *    下面程序选择了vector向量 vector <int> save(1, 0),初始化1个元素,值为0,循环体中,还需要一个用来确认位数 
  21.   *    的变量,申请int变量int weishu,刚刚开始时第0位,然后,进行位数上的数值递增操作,判断是否与基数相等, 
  22.   *    若不相等,则可以继续下一步的相加操作,若相等,则需要先将现在在进行操作的数组清零,然后,再将位数移到下一位, 
  23.   *   因为不知道下一位是否已经在vector里面申请了空间,所以,这里需要先做一个weishu与vector数组长度比较,以防止内存 
  24.   *    溢出,接下来只需要进入循环不断地判断是否执行进行操作就可以了。 
  25.   * 9. 在跳出了while(n--){]后,就意味着数值转换操作全部完毕,然后,只需要按顺序输出刚刚保存的向量就可以了。 
  26.   **/  
  27.   
  28. #include <iostream>  
  29. #include <vector>  
  30.   
  31. using namespace std;  
  32.   
  33. int main()  
  34. {  
  35.     int n, b;  
  36.     cin >> n >> b;  
  37.     vector <int> save(1, 0); // 初始化1个元素,值为0  
  38.     while(n--){  
  39.         int weishu = 0;  
  40.         while(b == ++save[weishu]){ // 此处进行加1的操作,然后判断是否能进位  
  41.             save[weishu] = 0;    // 清零进一  
  42.             ++weishu;  
  43.             if(save.size() < weishu + 1){    // 考虑进一时是否会越界  
  44.                 save.push_back(0);  
  45.             }  
  46.         }  
  47.     }  
  48.   
  49.     for (int i = save.size() - 1; i >= 0; --i){  
  50.         cout << save[i];  
  51.     }  
  52.     cout << endl;  
  53.   
  54.     return 0;  
  55. }  


 

  1. // Exercise_0307_进制转换2(base2)_x进制转十进制.cpp  
  2.   
  3. /** 
  4.  * 题目名称:进制转换2(base2) 
  5.  * 题目描述:输入基数b(2 <= b <= 10)和正整数n(b进制),输出n的十进制表示。 
  6.  **/  
  7.   
  8.  /** 
  9.   * 题目分析: 
  10.   * 1. 这题与上一题题目条件与结果刚刚相反,不过难度却增大了不少。 
  11.   * 2. 上一题是十进制转二进制,是已知十进制总数值大小的情况,相当于将数值逐个相加,可以使用进位的方法。 
  12.   * 3. 这一题是未知总数值大小,求十进制表示的总数值大小,将b进制的那个数,从最低位开始相减,为零则借位,直到全部位数为零。 
  13.   * 4. 这题关键点在于如何找到结束循环的条件,什么时候是借位结束,下面是部分的伪代码: 
  14.   *    while(未为全零){ // 这里循环刚刚开始时,可以先设一个bool值,用来标记这个数并非全为零,具体是否真为全零,可在循环中判断。 
  15.   *    if(检查到最低位为零){ 
  16.   *                          bool notAllZero = false; // 非全零标记 
  17.   *                          if(这个数值的全部位数都为零){ notAllZero = true;} // 这里的判断方法可以通过遍历每一位数来实现 
  18.   *                          else{ notAllZero = false;} 
  19.   *                          while(正在操作的位数 == 0){ 
  20.   *                                将这位数设为最大值; // 这里因为借位,如10-1的时候,本为0的那一位,变成了9 
  21.   *                                位数借一位;          // 将操作的位数借一位 
  22.   *                                if(刚刚所借的这一位数 == 0) 
  23.   *                                   { continue; 继续这一个循环;} // 因为之前做过判全零的操作,所以这里不用担心会有溢出的情况发生 
  24.   *                                else 
  25.   *                                   {这一位数数值-1; break;} // 数值正常减1后,借位成功,可以break出循环体 
  26.   *                         } 
  27.   *    else { 本位数值-1; }   // 最低位不为零时,操作非常简单,将这最低位的数值减1即可. 
  28.   *    ++result; // 这是用来记录十进制的总值的,每当成功完成一次减值操作,就可以将十进制这边的数值加1了。相当于将总数值转移到另一变量上保存。 
  29.   *    } 
  30.   * 5. 要完成刚刚那伪代码,可以知道,只需要初始化几个变量就可以了,表示位数的变量,表示全零的标记...具体实现方法请看代码。 
  31.   **/  
  32.   
  33. #include <iostream>  
  34. #include <cstring>  
  35. #include <string>  
  36.   
  37. using namespace std;  
  38.   
  39. int main()  
  40. {  
  41.     int b;  
  42.     string n;  
  43.     cin >> b >> n;  
  44.     int result(0);  
  45.   
  46.     const long weishuMaxIndex = n.length() - 1; // 最大下标代表最低位的数值  
  47.     bool notAllZero(true);  
  48.     while(notAllZero){  
  49.         int weishu = weishuMaxIndex;  
  50.         if ('0' == n[weishu]){  
  51.         // 判断是否全零,然后结束循环  
  52.             notAllZero = false;  
  53.             for(int i = weishuMaxIndex; i >= 0; --i){    // 判全零  
  54.                 if ('0' != n[i]){  
  55.                     notAllZero = true;  
  56.                     break;  
  57.                 }  
  58.             }  
  59.             if (false == notAllZero){       // 全部为零时,可直接结束循环  
  60.                 break;  
  61.             }  
  62.             while('0' == n[weishu]){        // 正在操作的位数上数值为零  
  63.                 n[weishu] = b + '0' - 1;    // 本位数上的数值设为最大  
  64.                 weishu = weishu - 1;        // 借一位,然后再开始判断操作  
  65.                 if ('0' == n[weishu]){      // 还是为零的话,继续循环操作  
  66.                     continue;  
  67.                 }  
  68.                 else{                       // 否则,可以数值减一,跳出循环,继续总体的下一步操作  
  69.                     n[weishu] = n[weishu] - 1;  
  70.                     break;  
  71.                 }  
  72.             }  
  73.         }  
  74.         else{  
  75.             n[weishu] = n[weishu] - 1;  
  76.         }  
  77.         ++result;  
  78.     }  
  79.     cout << result << endl;  
  80.   
  81.     system("pause");  
  82.     return 0;  
  83. }  


 

  1. // Exercise_0308_手机键盘(keyboard).cpp  
  2.   
  3. /** 
  4.  * 题目名称:手机键盘(keyboard) 
  5.  * 题目描述:输入一个由小写字母组成的英文单词,输出用手机的默认英文输入法的敲键序列。 
  6.  * 样例输入:pig 
  7.  * 样例输出: p1i3i1 
  8.  **/  
  9.   
  10.  /** 
  11.   * 题目分析: 
  12.   * 题目条件有4: 1. 九宫格 2. 用户输入英文单词 3. 根据九宫格输出按键顺序 4. 当按键前后相同时,需要输出同一字母 
  13.   * 首先,了解手机键盘上的九宫格是: (数字)1:(内容)空, 2:abc, 3:def, 4:ghi, 5:jkl, 6:mno, 7:pqrs, 8:tuv, 9:wxyz 
  14.   * 然后,要求用户输入一个单词。 
  15.   * 接着,输出这个按键序列,只需要使用一个switch语句判断每个字母需要在键盘上按键的数目,保存这个数目即可,另外再与现在的单词同步输出。 
  16.   * 最后,因为它还有一个条件需要去判断按键前后是否相同,我们可以再申请两个变量,用以保存前后两次的按键,再进行判断输出。 
  17.   * 另外,下面程序将preChar与nowChar初始化为不同的是为了防止第一次比较时会出现溢出,当它们相同的时候,会输出上一个字符,而首次输出时并不存在上一个字符之说。 
  18.   **/  
  19.   
  20. #include <iostream>  
  21. #include <cstring>  
  22. #include <string>  
  23.   
  24. using namespace std;  
  25.   
  26. int main()  
  27. {  
  28.     string word;  
  29.     cin >> word;  
  30.     long wordLongMax = word.length();  
  31.   
  32.     for(int wordLong = 0, preChar = 1, nowChar = 0; wordLong < wordLongMax; ++wordLong){  
  33.         int count = 0;  
  34.         switch(word[wordLong]){  
  35.             // 键盘上的数字2  
  36.             case 'a':   count = 1; nowChar = 2; break;  
  37.             case 'b':   count = 2; nowChar = 2; break;  
  38.             case 'c':   count = 3; nowChar = 2; break;  
  39.             // 键盘上的数字3  
  40.             case 'd':   count = 1; nowChar = 3; break;  
  41.             case 'e':   count = 2; nowChar = 3; break;  
  42.             case 'f':   count = 3; nowChar = 3; break;  
  43.             // 键盘上的数字4  
  44.             case 'g':   count = 1; nowChar = 4;  break;  
  45.             case 'h':   count = 2; nowChar = 4;  break;  
  46.             case 'i':   count = 3; nowChar = 4;  break;  
  47.             // 键盘上的数字5  
  48.             case 'j':   count = 1; nowChar = 5;  break;  
  49.             case 'k':   count = 2; nowChar = 5;  break;  
  50.             case 'l':   count = 3; nowChar = 5;  break;  
  51.             // 键盘上的数字6  
  52.             case 'm':   count = 1; nowChar = 6;  break;  
  53.             case 'n':   count = 2; nowChar = 6;  break;  
  54.             case 'o':   count = 3; nowChar = 6;  break;  
  55.             // 键盘上的数字7  
  56.             case 'p':   count = 1; nowChar = 7;  break;  
  57.             case 'q':   count = 2; nowChar = 7;  break;  
  58.             case 'r':   count = 3; nowChar = 7;  break;  
  59.             case 's':   count = 1; nowChar = 7;  break;  
  60.             // 键盘上的数字8  
  61.             case 't':   count = 1; nowChar = 8;  break;  
  62.             case 'u':   count = 2; nowChar = 8;  break;  
  63.             case 'v':   count = 3; nowChar = 8;  break;  
  64.             // 键盘上的数字9  
  65.             case 'w':   count = 1; nowChar = 9;  break;  
  66.             case 'x':   count = 2; nowChar = 9;  break;  
  67.             case 'y':   count = 3; nowChar = 9;  break;  
  68.             case 'z':   count = 1; nowChar = 9;  break;  
  69.   
  70.             default:  exit(1);  
  71.         }  
  72.         if (preChar == nowChar){  
  73.             cout << word[wordLong - 1] << count;  
  74.         }  
  75.         else{  
  76.             cout << word[wordLong] << count;  
  77.         }  
  78.         preChar = nowChar;     // 记录这次的字符是在哪一个区域,方便下次做“是否相同键”的判断  
  79.     }  
  80.     cout << endl;  
  81.     return 0;  
  82. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值