1. (2009年华中科技大学计算机研究生机试真题)成绩排序
题目描述:
用一维数组存储学号和成绩,然后,按成绩排序输出。
输入:
输入第一行包括一个整数N(1<=N<=100),代表学生的个数。
接下来的N行每行包括两个整数p和q,分别代表每个学生的学号和成绩。
输出:
按照学生的成绩从小到大进行排序,并将排序后的学生信息打印出来。
如果学生的成绩相同,则按照学号的大小进行从小到大排序。
样例输入:
3
1 90
2 87
3 92
样例输出:
2 87
1 90
题目描述:
用一维数组存储学号和成绩,然后,按成绩排序输出。
输入:
输入第一行包括一个整数N(1<=N<=100),代表学生的个数。
接下来的N行每行包括两个整数p和q,分别代表每个学生的学号和成绩。
输出:
按照学生的成绩从小到大进行排序,并将排序后的学生信息打印出来。
如果学生的成绩相同,则按照学号的大小进行从小到大排序。
样例输入:
3
1 90
2 87
3 92
样例输出:
2 87
1 90
3 92
源代码:
#include <stdio.h>
#define maxn 105
struct student
{
int num;
int score;
} stu[maxn];
void sort(struct student stu[],int n)
{
int i,j;
struct student t;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1-i;j++)
{
if(stu[j].score>stu[j+1].score || (stu[j].score==stu[j+1].score && stu[j].num>stu[j+1].num))
{
t=stu[j];
stu[j]=stu[j+1];
stu[j+1]=t;
}
}
}
}
int main()
{
int i,N;
while(scanf("%d",&N)!=EOF)
{
for(i=0;i<N;i++)
scanf("%d %d",&stu[i].num,&stu[i].score);
sort(stu,N);
for(i=0;i<N;i++)
printf("%d %d\n",stu[i].num,stu[i].score);
}
return 0;
}
程序截图:
2. (2010年北京大学计算机研究生机试真题)子串计算
题目描述:
给出一个01字符串(长度不超过100),求其每一个子串出现的次数。
输入:
输入包含多行,每行一个字符串。
输出:
对每个字符串,输出它所有出现次数在1次以上的子串和这个子串出现的次数,输出按字典序排序。
样例输入:
10101
样例输出:
0 2
01 2
1 3
10 2
101 2
源代码:
法一:一般解法:取子串+从子串中去出现次数>=2的子串+按字典序排序并输出
(接近一个小时的成果,经历了Runtime Error、Memory Limit Exceed各种错误后终于改对了:) )
#include <stdio.h>
#include <string.h>
#define maxn 100000
#define maxlen 105
char str[maxlen],tt[maxlen]; //临时字符串数组,用于排序函数中字符串的交换
char t[maxn][maxlen],result[maxn][maxlen]; //两个二维字符串数组分别保存取出的子串和经筛选后符合要求的子串
int time[maxn],visited[maxn]; //time数组记录每个子串的出现次数 visited数组记录子串是否已被访问
void sort(char str[][maxlen],int time[],int n) //将符合要求的子串按字典序排序
{
int i,j;
int k;
for(i=0;i<n-1;i++)
{
for(j=0;j<n-1-i;j++)
{
if(strcmp(str[j],str[j+1])>0) //子串前者比后者大,交换的时候注意同时交换子串和对应的出现次数
{
strcpy(tt,str[j]);
strcpy(str[j],str[j+1]);
strcpy(str[j+1],tt);
k=time[j];
time[j]=time[j+1];
time[j+1]=k;
}
}
}
}
void Judge_and_output(char t[][maxlen],char result[][maxlen],int n)//取符合要求的子串并输出
{
int i,j;
int k=0,first; //first用于判断子串是否是第一次出现
for(i=0;i<maxn;i++) //初始化子串次数为1,子串访问标记为0(未访问)
{
time[i]=1;
visited[i]=0;
}
for(i=0;i<n;i++) //求子串出现次数
{
first=1;
for(j=i+1;j<n;j++)
{
if(strcmp(t[i],t[j])==0 && visited[i]==0)
{
if(first==1)
{
strcpy(result[k],t[i]);
first=0;
}
time[k]++;
visited[j]=1;
}
}
visited[i]=1;
if(first==0) //发现子串,k++
k++;
}
sort(result,time,k); //将符合要求的子串按字典序排序
for(i=0;i<k;i++) //输出符合要求的子串及对应的出现次数
printf("%s %d\n",result[i],time[i]);
}
int main()
{
int i,j,k;
int count,num,Len;
while(scanf("%s",str)!=EOF)
{
count=1;
num=0,Len=0;
for(i=0;i<strlen(str);i++) //三重循环取子串
{
for(j=0;j+count<=strlen(str);j++) //注意下标j的要求:j加上子串长度要<输入的字符串长度
{
for(k=j;k<j+count;k++)
t[num][Len++]=str[k];
t[num][Len]='\0';
Len=0;
num++;
}
count++;
}
Judge_and_output(t,result,num); //取符合要求的子串并输出
memset(t,'\0',sizeof(t)); //每组输入结束后初始化两个二维字符串数组
memset(result,'\0',sizeof(result));
}
return 0;
}
法二:引用一种使用STL的解法
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main(int argc, char *argv[])
{
string str;
while (cin >> str)
{
map<string,int> mm;
for (int i = 0; i < str.size(); ++i)
{
for (int len = 1; len <= str.size() - i; ++len) //列举出所有的子串
{
string tmp = str.substr(i,len);
++mm[tmp];
}
}
map<string,int>::const_iterator ite;
for (ite = mm.begin(); ite != mm.end(); ++ite)
{
if (ite->second > 1)
cout << ite->first << " " << ite->second << endl;
}
}
return 0;
}
程序截图:
3. (2010年华中科技大学计算机研究生机试真题)a+b
题目描述:
实现一个加法器,使其能够输出a+b的值。
输入:
输入包括两个数a和b,其中a和b的位数不超过1000位。
输出:
可能有多组测试数据,对于每组数据,
输出a+b的值。
样例输入:
2 6
10000000000000000000 10000000000000000000000000000000
样例输出:
8
10000000000010000000000000000000
源代码:
#include <stdio.h>
#include <string.h>
#define maxn 1010
void Reverse(char *str) //字符串逆序
{
int i=0,j=strlen(str)-1;
char t;
while(i<j)
{
t=*(str+i);
*(str+i)=*(str+j);
*(str+j)=t;
i++,j--;
}
}
void BigAdd(char s1[],char s2[]) //大整数相加
{
int i=0,acc=0,j; //acc保存低位来的进位
int len1,len2;
int sum[maxn]={0}; //sum数组保存每一位相加的结果
len1=strlen(s1);
len2=strlen(s2);
Reverse(s1); //将两字符串逆序,从而从低位开始相加
Reverse(s2);
while(i<len1 && i<len2) //a与b的公共数位部分
{
sum[i]=(s1[i]-'0')+(s2[i]-'0')+acc; //注意从字符向整型数据的转化
if(sum[i]>=10) //判断是否有进位,如果有,进位标记=1,sum[i]-=10
{
sum[i]-=10;
acc=1;
}
else
acc=0;
i++;
}
while(i<len1) //a比b位数多时
{
sum[i]=s1[i]+acc-'0';
if(sum[i]>=10)
{
sum[i]-=10;
acc=1;
}
else
acc=0;
i++;
}
while(i<len2) //b比a位数多时
{
sum[i]=s2[i]+acc-'0';
if(sum[i]>=10)
{
sum[i]-=10;
acc=1;
}
else
acc=0;
i++;
}
if(acc==1) //最后判断最高为相加时是否有进位,如果有将进位的1作为结果最高位
sum[i++]=acc;
for(j=i-1;j>=0;j--) //从高位向低位输出每一位的值作为两大整数相加的结果
printf("%d",sum[j]);
printf("\n");
}
int main()
{
char num1[maxn],num2[maxn]; //注意a和b最多可达1000位,故用字符数组存储
while(scanf("%s %s",num1,num2)!=EOF)
BigAdd(num1,num2);
return 0;
}
程序截图: