请同学们先看提示,自行思考实践后无果再看通过代码。学习不要欺骗自己!!!
欢迎校友+q3023225096进行讨论交流
1.括号匹配(提示:栈)
题目编号:Exp04-Basic01,GJBook3例-06-13
题目名称:括号匹配
题目描述:编写程序,从终端读入以‘@’为结束符的字符序列(序列总长度不超过1000个字符),检查该字符序列中的 ( 与 )、 [ 与 ] 、{ 与 } 是否匹配(个数相等且位置不相交)。
输入:包含一串以‘@’为结束符的字符串,其间可能包含空白或其它非括号字符。
输出:如果字符串中三类括号匹配,则输出YES;否则输出NO。
样例1:
输入:
{a,a}b{c[cc]c} {a(bb[cc]dd)a}@
输出:
YES
样例2:
输入:
{a,a}b{c[cc]c] {a(bb[cc]dd)a}@
输出:
NO
了解栈的入门题
#include <stdio.h>
#include <stdlib.h>
/*以下两项分别是栈和栈顶指针,建议用全局声明*/
char stack[1000] = {""}; //初始化栈
int top=0; //初始化栈顶序号,其始终对应栈顶部的第一个空元素
void push(char ch); //入栈函数声明,把接收的元素压入栈中
char pop(void); //出栈函数声明,弹出并获取最顶部栈项
void check(char left, char right); //检查函数声明,左右括号匹配检查
int main() //主函数
{
for (char ch = getchar(); ch != '@'; ch = getchar()) //循环读取缓冲区字符并送入开关语句
switch (ch)
{
case '(': //只有左括号才入栈
case '[':
case '{':push(ch); break;
case ')':check(pop(), '('); break; //对右括号逐个检查匹配性
case ']':check(pop(), '['); break;
case '}':check(pop(), '{'); break;
}
printf("YES"); //如果能成功结束循环就YES,即所有括号匹配成功
return 0;
}
void push(char ch) //入栈函数定义
{
stack[top++] = ch;
}
char pop(void) //出栈函数定义
{
if (top > 0)
return stack[--top];
else
{
printf("NO");
exit(0); //栈空,出栈失败,打印NO并退出程序
}
}
void check(char left, char right) //检查函数定义
{
if (left != right) //如果弹出的元素不是右括号对应的左括号,即左接收值≠右接收值
{
printf("NO"); //括号不匹配,打印NO并退出程序
exit(0);
}
}
2.n倍数关系(提示:门槛在于处理输入数据)
题目编号:Exp04-Basic02
题目名称:n倍数关系
题目描述:
给定若干不完全相同的正整数(<10000)和n(n<5),计算这些正整数里面有多少数对满足:其中一个是另一个的n倍。例如:1 4 3 2 9 7 18 22,n=3时得到的答案是2;因为3是1的3倍,9是3的3倍。
输入:输入第一行给出正整数n的值,接下来包括多组测试数据。每组数据最多100个整数占用一行,以数字0结束(不计入100个整数里)。测试数据不超过20组,最后一行只包括-1,表示输入数据结束。输出:对每组输入数据,输出一行,给出有多少数对满足其中一个是另一个n倍。(注:最后一行末尾无换行符等多余字符。)
样例:
输入: 2 1 4 3 2 9 7 18 22 0 2 4 8 10 0 7 5 11 13 1 3 0 -1输出: 3 2 0
没啥好说的,方法很多
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i, j, l, n = 0, k = 0, r = 0;
int arr1[30] = { 0 };
scanf("%d", &n);
while (1)
{
int arr[200] = { 0 }; i = 0;
do
{
scanf("%d", &arr[i++]);
if (arr[i - 1] == -1) break;
} while (arr[i - 1] != 0);
if (arr[i - 1] == -1) break;
i--;
for (l = 0; l < i - 1; l++) //一定一动的遍历检查法,可以优化
for (j = l + 1; j < i; j++)
if (arr[l] == n * arr[j] || arr[l] * n == arr[j])
arr1[r]++;
r++;
}
for (int s = 0; s < r; s++)
{
if (k == 0)
{
k = 1; printf("%d", arr1[s]);
}
else printf("\n%d", arr1[s]);
}
return 0;
}
4.删除重复元素 (提示:样例没有负数)
题目编号:Exp04-Basic04,GJBook3-06-19
题目名称:删除重复元素
题目描述:编写函数,不使用其他辅助数组,把整型数组中重复元素删得只剩一个;所有未被删除元素都保留最先顺序移动到数组前面。
输入:第一行输入数组长度n(≤100),第二行依次从键盘随机输入n个整数作为数组元素值。输出:已删除重复元素的数组,各元素间以一个西文空格间隔,最后一个元素后无字符。
样例1:
输入: 10 1 1 2 3 3 3 2 1 2 4输出: 1 2 3 4样例2:
输入: 10 1 0 2 2 2 2 2 2 2 2输出: 1 0 2
卡bug,样例没有负数
#include<stdio.h>
int main()
{
int arr[101];
int i = 0, j = 0, n = 10;
scanf("%d", &n);
for (; i < n;) scanf("%d", &arr[i++]);
for (i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
if (arr[i] == arr[j]) arr[j] = -1;
}
for(j=0;n>0;j++,n--)
{
if (arr[j] == -1) continue;
if(j==0) printf("%d", arr[j]);
else printf(" %d", arr[j]);
}
return 0;
}
10.字符串反序 (提示:无)
题目编号:Exp04-Basic10,GJBook3-06-12
题目名称:字符串反序
问题描述:编写程序,将给定的字符串反序输出。
输入:一个长度不超过255的字符串,字符串中可能含有空白字符。
输出:反序输出的字符串。
样例1:
输入 A 输出 A
样例2:
输入 123 45 输出 54 321
两行够了
#include<stdio.h>
#include<string.h>
int main()
{
char arr[256]; gets(arr);
for (int i = strlen(arr) - 1; i >= 0; i--) printf("%c", arr[i]);
return 0;
}
11.约瑟夫环(提示:理解题意,可以用-1代表死人,0与肮数据混淆不能用)
题目编号 :Exp04-Enhance02,GJBook3-06-26
题目名称:约瑟夫问题(Josephus)
题目描述:
古代某法官要判决 n 个犯人死刑, 他有一条荒唐的逻辑, 将犯人首尾相接排成圆圈,所有计数从1开始; 然后从第 s 个人开始数, 每数到第 m 个犯人,则拉出来处决; 然后再数 m 个,数到的犯人再处决;... ; 但剩下的最后一个犯人可以赦免。编程序,给出处决顺序,并告知哪一个人活下来。
输入:三个正整数 n(≤1000),s和m,都可以使用int类型变量表示。
输出:依次输出被处决人员的编号,每个编号之间用一个西文空格间隔,最后一个编号后无字符。
样例:
输入:6 1 5输出:5 4 6 2 3 1
典型链表题,但是可以卡bug(滑稽)
#include<stdio.h>
int main()
{
int arr[1000] = { 0 }, n = 10, m = 10, s = 10, i, j, count, k = 0; //n为总人数,s为开始计数的序号,m为处决对应报的数
scanf("%d %d %d", &n, &s, &m); //i为当前人的序号,j为报的数,报数报到m即被处决
for (i = 1; i <= n; i++) arr[i] = i; //给所有人编序号
for (i = s, count = 0; count < n; count++)
{
for (j = 0;;)
{
if (i == n + 1) i = 1; //if-for-if 语块作用是实现循环报数并跳过死人轮到下一个活人
for (; arr[i] == -1; i++);
if (i == n + 1) i = 1;
j++; //当前的人报数
if (j == m) break; //报数报到m就处决
i++;
if (i == n + 1) i = 1; //同上
for (; arr[i] == -1; i++);
if (i == n + 1) i = 1;
}
if (k == 0) { printf("%ld", arr[i]); k = 1; } // if-else保持输出格式正确
else printf(" %ld", arr[i]); //先输出序号再处决
arr[i++] = -1; //赋值为-1即处决,并轮到下一个人
if (i == n + 1) i = 1; //同上
for (; arr[i] == -1; i++);
if (i == n + 1) i = 1;
}
return 0;
}
12. 英文翻译自然数(提示:数组的进阶初始化)
题目编号 :Exp04-Enhance03,freshman-1006
题目名称:英文翻译自然数
题目描述:按常规英文输出1000以内自然数的英文读法。
输入:每个测试输入包含 1 个测试用例,给出正整数 n(0<= n <1000)
输出:输出占一行:如果 0<= n <1000, 用规定的格式输出 n,所有英文单词小写,最后一个单词后无字符;否则输出ERR。
样例1:
输入:41输出:forty-one样例2:
输入:123输出:one hundred and twenty-three
这里也可以用二维数组存放多个字符串
#include<stdio.h>
#include<string.h>
int main()
{
int n = 0, i = 0, a, b, c;
char arr[4];
char* arr1[] = { "zero","one","two","three","four","five","six","seven","eight","nine" };
char* arr2[] = { "ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen" };
char* arr3[] = { "0","0","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety" };
gets(arr);
c = arr[2] - '0'; b = arr[1] - '0'; a = arr[0] - '0';
if (strlen(arr) == 3)
{
if (b > 1)
{
if (c > 0)
printf("%s hundred and %s-%s", arr1[a], arr3[b], arr1[c]);
else
printf("%s hundred and %s", arr1[a], arr3[b]);
}
else if (b == 1)
printf("%s hundred and %s", arr1[a], arr2[c]);
else if (b == 0)
{
if (c > 0)
printf("%s hundred and %s", arr1[a], arr1[c]);
else
printf("%s hundred", arr1[a]);
}
}
else if (strlen(arr) == 2)
{
if (a > 1 && b > 0)
printf("%s-%s", arr3[a], arr1[b]);
else if (a > 1 && b == 0)
printf("%s", arr3[a]);
else if (a = 1 && b > 0)
printf("%s", arr2[b]);
else if (a = 1 && b == 0)
printf("ten");
}
else printf("%s", arr1[a]);
return 0;
}
13.螺旋矩阵 (提示:找规律)
题目编号:Exp04-Enhance05,freshman-1050,GJBook3-0622
题目名称:螺旋矩阵
题目描述:
螺旋矩阵指一个呈螺旋状的数字矩阵,它的数字由第一行开始到右边不断变大,向下变大,向左变大,向上变大,如此循环。如下所示为3阶螺旋矩阵。
输入:输入一个正整数 N (N<=30),标明矩阵阶数。
输出:按螺旋矩阵形式输出整数 1~N^2, 共 N 行N 列,每个数字输出占4个西文字符宽度,右对齐,最后一个数字后无多余字符。
样例:
输入: 15输出:
本人的得意之作
#include<stdio.h>
int main()
{
int arr[30][30], i = 0, j = -1, n = 5, m, a, b, c, d;
scanf("%d", &n);
for (m = 0, b = n - 1, d = n; d > 0; b--, d--)
{
for (c = 0; c < d; c++) arr[i][++j] = ++m;
for (a = 0; a < b; a++) arr[++i][j] = ++m;
b--; d--;
for (c = 0; c < d; c++) arr[i][--j] = ++m;
for (a = 0; a < b; a++) arr[--i][j] = ++m;
}
for (i = 0, j = 0; i < n; i++)
{
if (i > 0) printf("\n");
for (j = 0; j < n; j++) printf("%4d", arr[i][j]);
}
return 0;
}