1、题目描述:输入一个IP地址串,判断是否合法。【华中科技大学】
示例代码:
#include
#include
#include
int main(){
int count, i;
while(scanf("%d", &count) != EOF){
for(i = 0; i < count; i++){
bool flag = true;
char *p;
char ipAddress[100];
scanf("%s", ipAddress);
p = strtok(ipAddress, ".");
while(p){
int tmp = atoi(p);
if(tmp < 0 || tmp > 255){
flag = false;
break;
}
p = strtok(NULL, ".");
}
if(flag){
printf("Yes!\n");
}else{
printf("No!\n");
}
}
}
return 0;
}
附注:
(1)stdlib库常用函数:
(2)string库常用函数:
2、题目描述:输入球的中心点和球上某一点的坐标,计算球的半径和体积。【清华大学】
示例代码:
#include
#include
int main(){
double pi = acos(-1), radius, volume;
double x0, y0, z0, x1, y1, z1;
while(scanf("%lf%lf%lf%lf%lf%lf", &x0, &y0, &z0, &x1, &y1, &z1) != EOF){
radius = sqrt(pow((x0 - x1), 2) + pow((y0 - y1), 2) + pow((z0 - z1), 2));
volume = 4.0 / 3 * pi * pow(radius, 3);
printf("%.3lf %.3lf", radius, volume);
}
return 0;
}
附注:
(1)math库常用函数:
3、题目描述:打印所有不超过n(n<256)的,其平方具有对称性质的数。如11*11=121。【北京理工大学】
示例代码:
#include
//求反序数
int reverse(int num){
int revNum = 0;
while(num != 0){
revNum *= 10;
revNum += num % 10;
num /= 10;
}
return revNum;
}
int main(){
for(int i =1; i < 256; i++){
int num = i * i;
if(reverse(num) == num){
printf("%d\n", i);
}
}
return 0;
}
4、题目描述:输入两个正整数,求其最大公约数。【哈尔滨工业大学】
示例代码1:
#include
int main(){
int a, b, minValue, result = 1;
scanf("%d%d", &a, &b);
minValue = a < b ? a : b;
if(a % b == 0){
printf("%d\n", b);
}else if(b % a == 0){
printf("%d\n", a);
}else{
for(int i = 2; i <= minValue / 2; i++){
if(a % i == 0 && b % i == 0){
a /= i;
b /= i;
result *= i;
}
}
}
printf("%d\n", result);
return 0;
}
示例代码2:
#include
int main(){
int a, b, tmp;
while(scanf("%d%d", &a, &b) != EOF){
while(b){
tmp = a % b;
a = b;
b = tmp;
}
printf("%d\n", a);
}
return 0;
}
5、题目描述:Finding all occurrences of a pattern in a text is a problem that arises frequently in text-editing programs.
Typically,the text is a document being edited,and the pattern searched for is a particular word supplied by the user.
We assume that the text is an array T[1..n] of length n and that the pattern is an array P[1..m] of length m<=n.We further assume that the elements of P and T are all alphabets(∑={a,b...,z}).The character arrays P and T are often called strings of characters.
We say that pattern P occurs with shift s in the text T if 0<=s<=n and T[s+1..s+m] = P[1..m](that is if T[s+j]=P[j],for 1<=j<=m).
If P occurs with shift s in T,then we call s a valid shift;otherwise,we calls a invalid shift.
Your task is to calculate the number of vald shifts for the given text T and p attern P.【上海交通大学】
示例代码:
#define MAX_SIZE 1000010
#include
#include
int main(){
char str[MAX_SIZE], subStr[MAX_SIZE];
char *pStr = str;
int appearCount;
while(scanf("%s%s", str, subStr) != EOF){
appearCount = 0;
char *tmp = strstr(pStr, subStr);
while(tmp){
pStr = tmp + 1;
appearCount++;
tmp = strstr(pStr, subStr);
}
printf("%d\n", appearCount);
}
return 0;
}
6、题目描述:读入任务调度序列,输出n个任务适合的一种调度方式。【中国科技大学】
示例代码:
#include
#include
#include
#define MAXSIZE 5000
//运用邻接表的思想
typedef struct ArcNode{ //边表
int adjvex; //该边所指向的结点位置
struct ArcNode *nextArc; //指向下一条边的指针
}ArcNode;
typedef struct TaskNode{ //任务结点表
char name[10]; //任务名称
int indegree; //记录入度
struct ArcNode *firstArc; //指向任务第一条边的指针
}TaskNode;
typedef struct StackNode{ //定义栈结点
char name[10]; //任务名称
struct StackNode *next; //指向下一个任务
struct ArcNode *firstArc; //指向任务第一条边的指针
}StackNode;
typedef struct MyStack{ //定义栈
struct StackNode *top; //栈顶指针
int taskCount; //栈中任务数量
}MyStack;
//初始化栈
MyStack* InitStack(){
MyStack *S = (MyStack *)malloc(sizeof(MyStack));
if(!S){
printf("MyStack Init failed.\n");
exit(1);
}
S->top = NULL;
S->taskCount = 0;
return S;
}
//入栈
void Push(MyStack *S, TaskNode *taskNode){
StackNode * stackNode = (StackNode *)malloc(sizeof(StackNode));
if(!stackNode){
printf("StackNode memory allocation failed.\n");
exit(1);
}
strcpy(stackNode->name, taskNode->name);
stackNode->next = S->top;
stackNode->firstArc = taskNode->firstArc;
S->top = stackNode;
S->taskCount++;
}
//出栈
void Pop(MyStack *S, StackNode **stackNode){
*stackNode = S->top;
S->top = (*stackNode)->next;
}
//拓扑排序思想输出任务调度序列
void TopoSort(TaskNode *taskList, int N, MyStack *S){
int popCount = 0;
for(int i = N - 1; i >= 0; i--){
if((taskList + i)->indegree == 0){ //入度为零,入栈
Push(S, (taskList + i));
(taskList + i)->indegree = -1;
}
}
while(S->top){
StackNode *stackNode = NULL;
Pop(S, &stackNode);
popCount++;
printf("%s ", stackNode->name);
ArcNode *arc = stackNode->firstArc;
while(arc){
--((taskList + arc->adjvex)->indegree);
arc = arc->nextArc;
}
if(!S->top){
for(int i = N - 1; i >= 0; i--){
if((taskList + i)->indegree == 0){ //入度为零,入栈
Push(S, (taskList + i));
(taskList + i)->indegree = -1;
}
}
}
free(stackNode);
stackNode = NULL;
}
if(popCount < N){ //弹出的任务数少于N,则任务存在死锁
printf("Task deadlock.\n");
}else{
printf("\n");
}
}
//删除字符串中某个特定字符(删除右括号)
char* DelChar(char *str, char ch){
int j = 0;
for(int i = 0; str[i] != '\0'; i++){
if(str[i] != ch){
str[j++] = str[i];
}
}
for(; str[j] != '\0'; j++){
str[j] = '\0';
}
return str;
}
//初始化任务列表
TaskNode* InitTaskList(int N){
TaskNode *taskListPoint = (TaskNode *)malloc(sizeof(TaskNode) * N); //为任务数组分配内存
if(!taskListPoint){ //内存分配失败
printf("TaskNode memory allocation failed.\n");
exit(1);
}
for(int i = 0; i < N; i++){ //初始化任务数组
char taskName[10];
char secondName[6];
strcpy(taskName, "Task");
itoa(i, secondName, 10);
strcat(taskName, secondName);
strcpy((taskListPoint + i)->name, taskName);
(taskListPoint + i)->firstArc = NULL;
(taskListPoint + i)->indegree = 0;
}
return taskListPoint;
}
//构造任务前后置关系
void InitTaskRelation(int N, TaskNode *taskListPoint){
for(int i = 0; i < N; i++){
TaskNode *pTask = taskListPoint;
char inputStr[MAXSIZE]; //用户输入的任务调度序列
scanf("%s", inputStr);
char *pBracket = strchr(inputStr, '(');
char code[6]; //任务编号变量
strncpy(code, inputStr + 4, strlen(inputStr) - strlen(pBracket)); //取出左括号前的前置任务编号
int taskNodeCode = atoi(code); //将前置任务编号从字符型转换为整型
pTask = pTask + taskNodeCode; //指向一个具体前置任务
if(!strstr(inputStr, "NULL")) {
DelChar(pBracket + 1, ')'); //删除右括号
char *pNext = strtok(pBracket + 1, ","); //按照逗号分割任务序列
for(int j = 0; pNext; j++){ //头插法插入后置任务
TaskNode *taskHead = taskListPoint;
struct ArcNode *arcNode = (struct ArcNode*)malloc(sizeof(struct ArcNode)); //创建一个边结点
char taskCode[6]; //任务编号变量
strcpy(taskCode, pNext + 4); //取出任务编号
arcNode->adjvex = atoi(taskCode); //将任务编号赋值给边结点所指任务位置变量
arcNode->nextArc = pTask->firstArc;
pTask->firstArc = arcNode;
(taskHead + atoi(taskCode))->indegree++;
pNext = strtok(NULL, ",");
}
}
}
}
//打印函数,用于测试输出
void print(int N, TaskNode *taskListPoint){
for(int i = 0; i < N; i++){
printf("name=%s\n", (taskListPoint + i)->name);
printf("indegree:%d\n", (taskListPoint + i)->indegree);
struct ArcNode* arcNode = (taskListPoint + i)->firstArc;
while(arcNode){
printf("它的后置任务是:%d\n", arcNode->adjvex);
arcNode = arcNode->nextArc;
}
}
}
int main(){
int N; //N:有n个任务
while(scanf("%d", &N) != EOF){
MyStack *S = InitStack();
TaskNode *taskListPoint = InitTaskList(N);
InitTaskRelation(N, taskListPoint);
//print(N, taskListPoint);
TopoSort(taskListPoint, N, S);
free(taskListPoint); //释放内存空间
taskListPoint = NULL;
}
return 0;
}
附注:
(1)字符串复制时,不能直接赋值,要用strcpy。
(2)当要往指针所指向变量赋值时,应先分配内存空间,分配时要检验是否成功,成功就可以使用指针。指针使用完成,要对申请的内存空间进行释放。malloc和free要成对使用。
(3)指针定义时,若没有指向,需要初始化为空,避免称为野指针,造成内存泄露。
(4).和->的区别:a).前面是结构体;b)->前面是指向结构体的指针变量;c)(*ArcNode).adjvex等效于ArcNode->adjvex。
7、题目描述:第一行输入一个数,为n,第二行输入n个数,这n个数中,如果偶数比奇数多,输出NO,否则输出YES。【北京航天航空大学】
示例代码:
#include
int main(){
int N;
while(scanf("%d", &N) != EOF){
int inputNumber, evenCount = 0, oddCount = 0;
for(int i = 0; i < N; i++){
scanf("%d", &inputNumber);
if(inputNumber % 2 == 0){
evenCount++;
}else{
oddCount++;
}
}
evenCount > oddCount ? printf("NO\n") : printf("YES\n");
}
return 0;
}
8、题目描述:在情报传递过程中,为了防止情报被截获,往往需要对情报用一定的方式加密,简单的加密算法虽然不足以完全避免情报被破译,但仍然能防止情报被轻易的识别。我们给出一种最简的的加密方法,对给定的一个字符串,把其中从a-y,A-Y的字母用其后继字母替代,把z和Z用a和A替代,则可得到一个简单的加密字符串。【北京大学】
示例代码:
#include
#include
void deal(char str[]){
int i = 0;
while(str[i] != '\0'){
if(str[i] == 'Z'){
str[i] = 'A';
}else if(str[i] == 'z'){
str[i] = 'a';
}else if((str[i] >= 'a' && str[i] <= 'y') || (str[i] >= 'A' && str[i] <= 'Y')){
str[i] += 1;
}
i++;
}
}
int main(){
char inputStr[90];
while(gets(inputStr)){
deal(inputStr);
printf("%s ",inputStr);
}
return 0;
}
附注:
(1)输入带空格的一行:scanf("%[^\n]",str)。
9、题目描述: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。【浙江大学】
示例代码:
#include
#include
#include
#include
#include
#include
using namespace std;
stack oper; //临时操作数栈
stack result; //后缀表达式结果栈
//删除空白字符
void deleteSpace(string &str){
str.erase(remove(str.begin(), str.end(), ' '), str.end());
}
//取得数字
double GetNumber(string s, int &index){
double number = 0;
while(isdigit(s[index])){
number = number * 10 + s[index] - '0';
index++;
}
return number;
}
//设置操作符优先级
int Priority(char c){
if(c == '*' || c== '/'){ //乘除优先级为2,加减优先级为1
return 2;
}else{
return 1;
}
}
double Calc(double a, double b, char c){
if(c == '+'){
return a + b;
}else if(c == '-'){
return a - b;
}else if(c == '*'){
return a * b;
}else{
return a / b;
}
}
//对加减乘除进行处理
double Deal(string s){
int i = 0;
do{
if(isdigit(s[i])){
result.push(GetNumber(s, i)); //取得运算数
}
//其后还有运算符 && 临时操作数栈为空||栈顶运算符优先级小于待入栈运算符
if(i < s.length() && (oper.empty() || Priority(oper.top()) < Priority(s[i]))){
oper.push(s[i++]); //操作符入临时操作数栈
}
//其后没有运算符 || 栈顶运算符优先级大于等于待入栈运算符
else if(i == s.length() || Priority(oper.top()) >= Priority(s[i])){
double b = result.top();
result.pop();
double a = result.top();
result.pop();
result.push(Calc(a, b, oper.top()));
oper.pop();
}
}while(i < s.length() || !oper.empty());
return result.top();
}
int main(){
string inputStr;
while(getline(cin, inputStr)){
if(inputStr == "0"){
break;
}
deleteSpace(inputStr);
cout.setf(ios::fixed);
cout << fixed << setprecision(2) << Deal(inputStr) << endl;
stack().swap(result); //重置栈
stack().swap(oper);
}
return 0;
}
附注:
(1)中缀表达式转换为后缀表达式思路:
10、题目描述:在一个果园里,小明已经将所有的水果打了下来,并按水果的不同种类分成了若干堆,小明决定把所有的水果合成一堆。每一次合并,小明可以把两堆水果合并到一起,消耗的体力等于两堆水果的重量之和。当然经过n‐1次合并之后,就变成一堆了。小明在合并水果时总共消耗的体力等于每次合并所耗体力之和。假定每个水果重量都为1,并且已知水果的种类数和每种水果的数目,你的任务是设计出合并的次序方案,使小明耗费的体力最少,并输出这个最小的体力耗费值。例如有3种水果,数目依次为1,2,9。可以先将1,2堆合并,新堆数目为3,耗费体力为3。然后将新堆与原先的第三堆合并得到新的堆,耗费体力为 12。所以小明总共耗费体力=3+12=15,可以证明 15 为最小的体力耗费值。【吉林大学】
示例代码:
#include
#include
int cmp(const void *a, const void *b){
return *(int *)b - *(int *)a;
}
void AdjustSort(int fruit[], int n){
int i, tmp, newNumber = fruit[n - 1];
for(i = n - 2; i >= 0; i--){
if(newNumber > fruit[i]){
fruit[i + 1] = fruit[i];
}else{
break;
}
}
fruit[i + 1] = newNumber;
}
int main(){
int n;
while(scanf("%d", &n) != EOF){
int *fruit = (int *)malloc(sizeof(int) * n);
for(int i = 0; i < n; i++){
scanf("%d", &fruit[i]);
}
qsort(fruit, n, sizeof(int), cmp);//由小到大排序
int result = 0;
while(n > 1){
int min = fruit[--n];
int secondMin = fruit[--n];
fruit[n++] = min + secondMin;
result += min + secondMin;
AdjustSort(fruit, n);
}
printf("%d\n", result);
}
return 0;
}
附注:
(1)qsort函数:对数组元素进行排序,void qsort(fruit, n, sizeof(int), cmp)。
[1]杨泽邦、赵霖. 计算机考研——机试指南(第2版). [M]北京:电子工业出版社,2019.11;