1.第一题 A+B
C语言代码
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<malloc.h>
int main(){
const char data[12][6] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "+", "="};
unsigned a, b; //转换后的参数表达式参数, 如a+b(123+456)
unsigned i, j, k; //临时变量, 作为下标
char str[100]; //输入字符串, 足够大容量
char temp[6]; //临时字符串, 用于检索数字, 如"one" -> 1
char result[301]; //转换后的表达式参数, 如"123+456="
do{
a = b = i = j = k = 0; //初始化变量
memset(str, 0, sizeof(str));
memset(temp, 0, sizeof(temp));
memset(result, 0, sizeof(result));
gets(str); //获取输入字符串, 不能使用scanf, 因为有空格
for(i = 0, k = 0; i < strlen(str); ++i){
for(j = 0; !isspace(str[i]) && i < strlen(str); ++i, ++j){ //提取一个单词
temp[j] = str[i];
}
temp[j] = '\0'; //字符串结束标记
for(j = 0; j < 12; ++j){ //把这个单词转换为数字
if(strcmp(temp, data[j]) == 0){
if( j <= 9) result[k++] = j + '0'; //转换后0-9
if( j == 10) result[k++] = '+';
if( j == 11) result[k++] = '=';
break; //找到匹配数字就不必再搜索了
}
}
}
result[k] = '\0'; //字符串结束标志, result形式"123+456="
sscanf(result, "%d+%d=", &a, &b); //用sscanf来获得a,b的值
if(a==0 && b==0) break; //A,B同时为0则退出程序
else printf("%d\n", a + b); //打印输出A + B的数值
}while(1);
return 0;
}
2.谁是开门关门的人?
C语言代码
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct{
char id[16]; //证件号码长度不超过15位
char cometime[9]; //时间格式00:00:00
char leavetime[9]; //时间格式00:00:00
}Record;
int main(){
int N, M, i; //记录总天数N, 每天记录的条目数M
Record *pTimeList; //记录该天出入人员的证件号码, 进入时间, 离开时间
int first, last; //记录每天开门的人和关门的人
scanf("%d", &N); //读入记录的天数
while(N--){
scanf("%d",&M); //读入该天的进出人员数
pTimeList = (Record*)malloc(M*sizeof(Record));
for(i = 0, first = 0, last = 0;i < M; ++i){
scanf("%s%s%s", pTimeList[i].id, pTimeList[i].cometime, pTimeList[i].leavetime);
if(i==0){ //将第一个设为对比值
continue;
}else{ //不需要对comeTime或者lastTime进行删减,直接对比
if(strcmp(pTimeList[first].comeTime, pTimeList[i].cometime) > 0){
first = i; //更换first
}
if(strcmp(pTimeList[i].leavetime, pTimeList[i].leavetime) < 0){
last = i;//更换last
}
}
}
printf("%s %s\n",pTimeList[first].id, pTimeList[last].id);
free(pTimeList);
}
return 0;
}
3.分数统计
题目
C语言代码
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct
{
char id[21]; //准考证号(<=20字符)
int score; //该考生总分
}StuInfo;
int main(){
int N, M, G, n; //考生人数, 题目数, 分数线, 上线考生数量
int *pMarkList; //第1题至第M题的正整数分值
StuInfo *pStuinfo; //考生信息
int i, j, k, a, b, c, m; //临时变量
StuInfo tmp; //用于排序
while(scanf("%d",&N)&&N!=0){//读入考生人数N
scanf("%d%d",&M,&G); //读入题目数和分数线
pMarkList = (int*)malloc(M*sizeof(int)); //M道题目的分数
pStuinfo = (StuInfo*)malloc(N*sizeof(StuInfo)); //N个考生
for(i = 0;i<M;++i){ //读入M题每题分数
scanf("%d",&(pMarkList[i]));
}
for(i = 0, n = 0;i<N;++i){ //读入N个考生信息, i用于计数N次,cnt用于计算上线考生记录
scanf("%s%d",&(pStuinfo[n].id), &m); //准考证号, 解出题目数量m
for(pStuinfo[n].score = 0, j = 0;j<m;++j){ //读入答出的m题的题号
scanf("%d",&a); //读入答对的题号
pStuinfo[n].score += pMarkList[a-1]; //因为题目号从1开始, 计算该考生的总分
}
if(pStuinfo[n].score >=G){ //如果考生上线则记录下来
n++; //否则不记录, 便于排序
}
}
for(i = 0;i < n - 1;++i){//输入完毕, 对上线考生按分数线排序, 降序
for(k = i, j = i + 1;j<n;++j){ //如果有比pStuinfo[i]大的,把它和pStuinfo[i]交换
if(pStuinfo[n].score > pStuinfo[k].score){
k = j;
}
}
tmp = pStuinfo[k];
pStuinfo[k] = pStuinfo[i];
pStuinfo[i] = tmp;
}
for ( i = 0; i < n; i+=k)
{ //相同分考生再按照准考证号排序
//统计相同分数考生人数
for(k = 1, j = i + 1;j <n ;++j){
if(pStuinfo[i].score == pStuinfo[j].score){
k++;
}
else
{
break;
}
}
//下标i到i+k的考生分数相同, 对这k个考生排序, 升序
for(a = i; a<=i+k-1;a++){
for(c = a, b = a + 1;b<=i+k;++b){
if(strcmp(pStuinfo[c].id, pStuinfo[b].id)){
c = b;
}
}
tmp = pStuinfo[a];
pStuinfo[a] = pStuinfo[c];
pStuinfo[c] = tmp;
}
}
printf("%d\n", n);//排序完毕, 按照要求输出, 上线人数
for(i = 0;i<n;++i){//和每个上线考生的准考证号和总分数
printf("%s %d\n",pStuinfo[i].id, pStuinfo[i].score);
}
free(pMarkList);
free(pStuinfo);
}
return 0;
}
4.最大连续子序列
C语言代码
#include<stdio.h>
#include<malloc.h>
#include<limits.h>
int main(){
long int K, last; //输入数据个数K<1000; 最大子序列最后一个元素的下标last
long int ThisSum, MaxSum, TmpMaxSum, index, *pList;
while(scanf("%d",&K) && K){
ThisSum = 0;
MaxSum = TmpMaxSum = last = LONG_MIN;
pList = (long int*)malloc(K*sizeof(long int));
for(index = 0;index < K;index++){
scanf("%d", &(pList[index]));
ThisSum += pList[index];
if(ThisSum > MaxSum){ //输入含有正数时, 忽略最大子序列中首尾0的影响
MaxSum = ThisSum; //更新MaxSum
if(MaxSum > TmpMaxSum){
//保证最大子序列起始位置在输入串的最前面
TmpMaxSum = MaxSum;
last = index;
}
}
if(ThisSum <0 ) ThisSum = 0;
}
//trace back to find first number of the max subsequence
for(TmpMaxSum = 0, index = last;index>=0;index--){
TmpMaxSum += pList[index];
if(TmpMaxSum == MaxSum){
break;
}
}
if(MaxSum<0) { //K个数字都是负数, 定义最大和为0, 输出首尾元素
printf("%ld %ld %ld\n",0, pList[0], pList[k-1]);
}else{
printf("%ld %ld %ld\n",MaxSum,pList[index],pList[last]);
}
free(pList);
}
return 0;
}
C语言代码
#include<stdio.h>
#include<malloc.h>
#include<limits.h>
int main(){
long int K, last; //输入数据个数K<1000; 最大子序列最后一个元素的下标last
long int ThisSum, MaxSum, TmpMaxSum, index, *pList;
while(scanf("%d",&K) && K){
ThisSum = 0;
MaxSum = TmpMaxSum = last = LONG_MIN;
pList = (long int*)malloc(K*sizeof(long int));
for(index = 0;index < K;index++){
scanf("%d", &(pList[index]));
ThisSum += pList[index];
if(ThisSum > MaxSum){ //输入含有正数时, 忽略最大子序列中首尾0的影响
MaxSum = ThisSum; //更新MaxSum
if(MaxSum > TmpMaxSum){
//保证最大子序列起始位置在输入串的最前面
TmpMaxSum = MaxSum;
last = index; //现在找到的最大值和的末尾元素
}
}
if(ThisSum < 0) ThisSum = 0;
}
//trace back to find first number of the max subsequence
for(TmpMaxSum = 0, index = last;index>=0;index--){
TmpMaxSum += pList[index];
if(TmpMaxSum == MaxSum){ //这时也找到了index
break;
}
}
if(MaxSum<0) { //K个数字都是负数, 定义最大和为0, 输出首尾元素
printf("%ld %ld %ld\n",0, pList[0], pList[k-1]);
}else{
printf("%ld %ld %ld\n",MaxSum,pList[index],pList[last]);
}
free(pList);
}
return 0;
}
5.畅通工程
4城2路
4 2
1 3
4 3
3城3路
3 3
1 2
1 3
2 3
5城2路
5 2
1 2
3 5
999城0路
999 0
算法:
并查集:如果两个城镇非连通,则将它们各自所在树的根结点连通即可;每次合并城镇时将城镇数-1,最后只需要输出城镇
数-1即可(N个城镇用N-1条路即可连接).
C语言代码
//并查集
#include<stdio.h>
#include<stdlib.h>
int count=0;
int *arr;
int flag[1005];
int findFather(int jieDian){
return jieDian==arr[jieDian]?jieDian:findFather(arr[ arr[jieDian] ]);
}
int main(){
while(1){
int N;
scanf("%d",&N);
if(N==0){
break;
}
int sava_N=N;
count++;
int M;
scanf("%d",&M);
arr=(int *)malloc(sizeof(int)*(N+1)); //存储城镇
for(int i=1;i<=N;i++){
arr[i]=i; //指向本身
}
for(int i=1;i<=M;i++){
int relation_One;
int relation_Two;
scanf("%d%d",&relation_One,&relation_Two);
int fa_One=findFather(relation_One);
int fa_Two=findFather(relation_Two);
if(fa_One!=fa_Two) {
sava_N--;
if(fa_One<fa_Two){
arr[fa_Two]=fa_One;
}
else{
arr[fa_One]=fa_Two;
}
}
}
flag[count]=sava_N-1;
}
for(int i=1;i<=count;i++){
printf("%d\n",flag[i]);
}
return 0;
}