文章目录
A. 身份证号码最后一位
以下是AC代码
#include<stdio.h>
//#define SIZE 101
int main()
{
int t,i,xishu[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2},yushu=0;
char a[18],t1;
scanf("%d",&t);//输一个1进去,输出-38?
//printf("%d\n",t);
while(t)
{
yushu=0;
scanf("%s",a);
//printf("%c\n",a[17]);
/*for(i=0;i<18;i++)
{
scanf("%c",&a[i]);//b[i]=a[i]-48;
printf("%d\n",a[i]);//表示成a[i]-48没错
}*/
//printf("%c",a[17]);
for(i=0;i<17;i++)
{
//printf("%d %d\n",b[i],xishu[i]);
yushu+=(a[i]-'0')*xishu[i];
//printf("%d\n",yushu);
}
yushu=yushu%11;
//printf("%d\n",yushu);//yushu=-2?
switch(yushu){
case 0:t1='1';break;
case 1:t1='0';break;
case 2:t1='X';break;//X要大写??!!,唉
case 3:t1='9';break;
case 4:t1='8';break;
case 5:t1='7';break;
case 6:t1='6';break;
case 7:t1='5';break;
case 8:t1='4';break;
case 9:t1='3';break;
case 10:t1='2';break;
}
//printf("%c %c\n",t1,a[17]);//a[18]有毛病。
if(a[17]==t1)printf("right\n");
else printf("wrong\n");
t--;
}
return 0;
}
这题还有一些问题存在:
1、为什么以下代码输出有问题?
#include<stdio.h>
int main()
{
int t=0,i;
char a[18];
scanf("%d",&t);
while(t)
{
for(i=0;i<18;i++)
{
scanf("%c",&a[i]);
printf("%d\n",a[i]);
}
t--;
}
return 0;
}
输入1,为t的值,a还没输入,按理不应有输出,但它输出了10
不输入也有输出。。
找到原因:换行符LF ascii码值为10,输入t后换行符被读入a[i]
2、本题,据老师说是数据问题(换行符?),使用循环+scanf("%c",&a[i]);不能通过,只能用scanf("%s",a);读入数据才能过。
3、switch可以换成另1个数组。如下:
b[11]={1,0,X,9,8,7,6,5,4,3,2};
if(b[yushu]==a[17])printf("right\n");
else printf("wrong\n");
C. 实验9_3_字母统计
运行时间限制: 1000 运行内存限制: 65536
作者: scshuanghai 是否specialjudge: False
题目描述
问题描述:
任意给定一个字符串,字符串中包含除了空格、换行符之外的的任意字符。你的任务是统计出现在该字符串中的各字母(即“A—Z”,“a—z”)的个数(区分大小写)。
输入与输出要求:
输入一个长度不超过100的非空字符串。字符串中不会出现空格、换行符。输出字符串中出现的字母的统计信息,每个字母的统计信息占一行,按照字母的ASCII码的顺序输出。
程序运行效果:
AAAsdf&^%DF879as↙
The character A has presented 3 times.↙
The character D has presented 1 times.↙
The character F has presented 1 times.↙
The character a has presented 1 times.↙
The character d has presented 1 times.↙
The character f has presented 1 times.↙
The character s has presented 2 times.↙
注意单词“time”不论单复数,一律输出复数形式“times”。
这个题,不难,记录一下出现的小问题,不记得ascii码值
神特么大写字母和小写字母之间还插了6个乱七八糟的字符
#include<stdio.h>
#include<string.h>//使用memset需要的头文件
#define SIZE 101
int main()
{
char a[SIZE];
scanf("%s",a);
int i,b[SIZE];
memset(b,0,sizeof(b));//数组清0
//判断在A~Z,与a~z之间,计数
for(i=0;a[i]!='\0';i++)
{
if(((a[i]<='Z')&&(a[i]>='A'))||((a[i]<='z')&&(a[i]>='a')))
b[a[i]-'A']++;
}
for(i=0;i<58;i++)//26+32//此处不是26个大写字母加26个小写字母,还有中间6个。
{
if(b[i]!=0)printf("The character %c has presented %d times.\n",i+'A',b[i]);
else continue;
}
return 0;
}
关于memset:
memset()函数原型是extern void *memset(void *buffer, int c, int count)
buffer:为指针或是数组,
c:是赋给buffer的值,
count:是buffer的长度.(暂时先不深究)
B. 实验9_1_括号匹配
运行时间限制: 1000 运行内存限制: 65536
作者: scshuanghai 是否specialjudge: False
题目描述
问题描述:
任意给定一个字符串,字符串中包含除了空格、换行符之外的任意字符。你的任务是检测字符串中的小括号是否配对,即“(”与“)”是否配对。如字符串“((a+b)(c+d))”中小括号是配对的,而“((a+b))c+d))”则不配对。
输入与输出要求:
输入一个长度不超过100的非空字符串,该字符串中不会出现空格、换行符。输出检测结果。
程序运行效果:
Sample 1:
((a+b)*(c+d)) ↙
parentheses match!↙
Sample 2:
((a+b)*)c+d)) ↙
parentheses do not match!↙
这题,我好迷,思路简单,也易写,但是,出现了一个神奇的错误。先贴上AC代码
//先写一下思路:需要一个东西统计左括号的数量,如果右括号能找到左括号就匹配,左括号数量最后为0,就匹配
//先写一下思路:需要一个东西统计左括号的数量,如果右括号能找到左括号就匹配,左括号数量最后为0,就匹配
#include<stdio.h>
#define SIZE 101
int main()
{
char a[SIZE];
int i,left=0,flag=1;
scanf("%s",a);
for(i=0;a[i]!='\0';i++)
{
if(a[i]=='(')left++;
//if((a[i]==')')&&left>0)left--;
if(a[i]==')'&&left<=0){flag=0;break;}
else if(a[i]==')')left--;
printf("%c\n",a[i]);//**为啥不会被同化为')'?**
}
if(left==0&&flag==1)printf("parentheses match!\n");
else printf("parentheses do not match!\n");
return 0;
}
以下是出问题的代码:
#include<stdio.h>
//数组做形参,尝试
//有点乱了,这题,是要移动指针。可以是数组坐标 思路思路,咋整。
#define SIZE 101
int main()
{
char a[SIZE];
int left=0,i,flag=1;
scanf("%s",a);
//printf("%s\n",a);
for(i=0;a[i]!='\0';i++)
{
if(a[i]=='(')left++;//不能根据数量来判断
if((left<=0)&&(a[i]==')')){flag=0;break;}//有右括号,前无左括号
else if(a[i]=')')left--; //少了个等于
//else flag=0,break;//如果左括号数量小于等于0或 a[i]!=')'flag=0;//有问题
//if(left<0)
/*if(a[i]=='(')right++;
if(a[i]==')')right--;*/
printf("%c\n",a[i]);//**为啥会被同化为')'?**
//printf("%d\n",left);
}
//printf("%d\n",left);
if((flag==1)&&(left==0))printf("parentheses match!\n");
else printf("parentheses do not match!\n");
return 0;
}
两个代码画** **部分输出不一样,AC的是这样
没过的是这样:
后来发现,因为少了个=
else if(a[i]=’)’)left–; //这句
升级版的冒泡排序:升级之处在于,确定了的数就不重复比较
选择排序:将某一范围内的最大值提到最前,剔除第一个接着排序之后的,选出第二大值赋给第2个数…如此循环(降序排序)
F. 实验7_12_设计函数**(插入排序)**
运行时间限制: 1000 运行内存限制: 65536
作者: scshuanghai 是否specialjudge: False
题目描述
void InsertSort(int a[],int n); 使用插入排序算法,将数组a的前n个元素按照升序的方式排序。
插入排序算法描述如下:
初始序列:49 38 65 97 76 13 27 49
将元素(38) 插入合适位置: [38 49] 65 97 76 13 27 49
将元素(65) 插入合适位置: [38 49 65] 97 76 13 27 49
将元素(97) 插入合适位置: [38 49 65 97] 76 13 27 49
将元素(76) 插入合适位置: [38 49 65 76 97] 13 27 49
将元素(13) 插入合适位置: [13 38 49 65 76 97] 27 49
将元素(27) 插入合适位置: [13 27 38 49 65 76 97] 49
将元素(49) 插入合适位置: [13 27 38 49 49 65 76 97]
输入与输出要求:首先输入一个整数n(1<=n<=1000),代表待排序元素的个数。然后输入n个整数,每个整数不会超过int型的存储范围。输出为n-1行,依次为1到n-1趟排序后数组内各个元素。每行输出的顺序为a[0]至a[n-1],数与数之间用空格分开,注意第n个数后没有空格而是换行符。
输入样例
8
49 38 65 97 76 13 27 49
输出样例
38 49 65 97 76 13 27 49
38 49 65 97 76 13 27 49
38 49 65 97 76 13 27 49
38 49 65 76 97 13 27 49
13 38 49 65 76 97 27 49
13 27 38 49 65 76 97 49
13 27 38 49 49 65 76 97
#include<stdio.h>
#define SIZE 1001
void insertSort(int [],int);
int main()
{
int n,i,a[SIZE];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
insertSort(a,n);
return 0;
}
//怎么顺移? 怎么插入
void insertSort(int a[],int n)
{
int i,j,t,k;
for(i=1;i<n;i++)//满足的插入条件为:j<i,并且a[j]>a[i]
{
int j=0;//初始化j,每次都从a[0]开始查找是否能插入 ,j在有序组移动
while((j<i)&&(a[j]<a[i]))//此时 不满足,接着找
j++;
if(i!=j)//如果i=j说明恰好在正确位置上
{
t=a[i];
for(k=i;k>j;k--)
{
a[k]=a[k-1];
}
a[j]=t;
}
for(k=0;k<n-1;k++)
printf("%d ",a[k]);
printf("%d\n",a[n-1]);
}
}
G. 实验7_15_设计函数**(选择排序)**
运行时间限制: 1000 运行内存限制: 65536
作者: scshuanghai 是否specialjudge: False
题目描述
void SelectSort(int a[],int n); 使用选择排序算法对数组a的前n个元素按照升序的方式排序。
选择排序算法描述如下:
从a[0]~ a[n-1]这段元素中找最小元素a[min],a[0]和a[min]交换;接着,从a[1]~ a[n -1]这段元素中找最小元素a[min],a[1]和a[min]交换;依次类推,直到从a[n-2]~a[n -1]这段元素中找最小元素a[min],a[n-2]和a[min]交换。
输入与输出要求:首先输入一个整数n(1<n<=1000),代表待排序元素的个数。然后是n个整数,每个整数不会超过int型的存储范围
输出为n-1行,依次为1到n-1趟排序后数组内各个元素。每行输出的顺序为a[0]至a[n-1],数与数之间用空格分开,注意第n个数后没有空格而是换行符。
建议设计两个辅助函数:
函数功能:找数组中的最小值元素,并返回其下标
参数说明:数组名,查找起始位置下标,查找终止位置下标
int findMin(int data[], int startLoc, int endLoc) ;
函数功能:依次输出数组中各个元素,数与数之间用空格分开,最后一个数后没有空格而是换行符
参数说明:数组名,数组内元素个数
void outputData(int data[],int elementCount) ;
输入样例
8
49 38 65 97 76 13 27 4
输出样例
4 38 65 97 76 13 27 49
4 13 65 97 76 38 27 49
4 13 27 97 76 38 65 49
4 13 27 38 76 97 65 49
4 13 27 38 49 97 65 76
4 13 27 38 49 65 97 76
4 13 27 38 49 65 76 97
这题思路是:找出最小的(写一个程序,返回最小数的坐标),和第一个交换,剩下的找最小的,和第二个交换。
#include<stdio.h>
#define SIZE 1001
void SelectSort(int [],int);
int findMin(int a[], int startLoc, int endLoc);
int main()
{
int n,i,a[SIZE];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
SelectSort(a,n);
return 0;
}
void SelectSort(int a[],int n)
{
int i,j,t,k;
for(i=0;i<n-1;i++)//交换
{
j=findMin(a,i,n);
t=a[j];
a[j]=a[i];
a[i]=t;
for(k=0;k<n-1;k++)
printf("%d ",a[k]);
printf("%d\n",a[n-1]);
}
}
//函数分解比较简单,容易理清思路
int findMin(int a[], int startLoc, int endLoc)
{
int i,min=a[startLoc],t=startLoc;
for(i=startLoc+1;i<endLoc;i++)
{
if(a[i]<min)//交换,保留下标
{min=a[i];t=i;
}
}
return t;
}
H. 实验7_17_设计函数**(二分查找)**
运行时间限制: 1000 运行内存限制: 65536
作者: scshuanghai 是否specialjudge: False
题目描述
int BinarySearch(int a[],int n,int key);利用二分查找算法,在升序排列的数组a的前n个元素中查找值为key的数组元素的下标。如果数组a中存在整数key,则返回下标;否则返回-1。假设数组a中的元素互不相同。
输入与输出要求:首先输入两个整数n,m,分别代表数组a中元素的个数与需要查找的整数的个数,n(0<n<=2000000)与m(0<m<=100000)。然后分别输入n个整数和m个整数,分别代表存放在数组中的数以及要查找的数。输出m个整数,分别为要查找的数在数组a中的下标,如果数组a中不存在某个数,则输出-1。数与数之间用空格分开,注意第n个数后没有空格而是换行符。
注意:
1、由于n比较大,建议使用全局变量存储这n个整数;
2、由于数据量较大,建议输入时使用scanf()函数。
程序运行效果:
Sample 1:
15 ↙
20↙
-293 -213 -23 0 1 5 11 23 56 67 87 273 999 2132 10000↙
-23 -99999 0 999 953 67 56 44 33 87 -293 23 11 273 -213 2132 10000 87654 1 5↙
2 -1 3 12 -1 9 8 -1 -1 10 0 7 6 11 1 13 14 -1 4 5
这题,输入的第一个数组本身就是排好序的,我还又给排了一遍。。于是超时了。
这题重点是排序然后二分查找。(我总觉得如果某题需要排完序再查找会超时)
#include<stdio.h>
#define SIZE 1001
int BinarySearch(int [],int);
int n;
int main()
{
int i,a[20001],m,b[1001];
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
int j,t;
/*for(i=0;i<n;i++)
for(j=0;j<n-1;j++)//排序a
{
if(a[j]>a[j+1])t=a[j],a[j]=a[j+1],a[j+1]=t;
}*/
for(i=0;i<m-1;i++)
{
scanf("%d",&b[i]);
printf("%d ",BinarySearch(a,b[i]));
}
scanf("%d",&b[m-1]);
printf("%d\n",BinarySearch(a,b[m-1]));
return 0;
}
int BinarySearch(int a[],int key)
{
int left,right,mid;
/*int i,flag=0;
for(i=0;i<n;i++)事实证明,直接上查找是会超时的
if(a[i]==key)
{
flag=1;return i;
}
else if(flag==0&&key<a[i])return -1;*/
left=0;right=n-1;
while(left<=right)//此处等于非常重要,相等后,mid,left,right就是一个数,要找的如果不是它,那就返回-1
{
mid=left+(right-left)/2;
if(key>a[mid])left=mid+1;
else if(key<a[mid])right=mid-1;
else return mid;
}
return -1;
}