PAT (Basic Level) Practise (中文)1001——1034C语言实现

题目链接:https://www.patest.cn/contests/pat-b-practise

最近想学CS,看看自己是否适合编程,所以就来pat上做做编程题,都是用c语言编写的,有些思路不是特别好,仅供参考,会逐渐更新。废话不多说了,开始吧!!!

1001.害死人不偿命的(3n+1)猜想 (15)
题意:一个正整数n,按照卡拉兹(Callatz)猜想: 偶n=n/2;奇n=(3n+1)/2 的规律进行下去。最终会使n=1;
问操作的步骤数为多少。
思路 :(1)判断n是否为1。(2)再判断奇偶性,执行相应的操作,步骤数加一。(3)重复(1)(2)直到n=1
注意点
(1)自然数是从0开始的,但好似题目并没有考虑0的情况。
(2)是先判断是否为1,也就是说当n=1时,步骤数为0, 不是3(1,2,1)
#include<stdio.h>        //自然数包括0,1,2,3…… 
int main() 
{
	int n,i=0;
	scanf("%d",&n);
    if(n!=1)            //主要是注意1,不是先判断是否为奇偶 
    {
	do{
	if(n%2==0)n/=2;
	else n=(3*n+1)/2; 
	i++;
    }while(n>1);
}
    printf("%d\n",i);
    return 0;
}
1002.写出这个数 (20)
题意:读入一个自然数n, 计算其各位数字之和 ,用汉语拼音写出和的每一位数字。
思路 :因为位数比较多100位(最多),所以用一维字符数组str[101]储存数据,然后求每位数字之和sum,用一个二维字符数组存储数字的拼音,再得到sum的每一位,从高位开始输出拼音。
注意点 :注意输出格式及最后没有 空格
#include<stdio.h>
#include<string.h>
char a[10][5]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
void pf(int n)
{
	if(n<10) printf("%s",a[n]);
	else pf(n/10),printf(" %s",a[n%10]);
}
int main()
{
	char str[100];
	gets(str);
	int S=0,n=strlen(str);
	for(int i=0;i<n;i++)S+=(str[i]-'0');
	pf(S);
	return 0;
}
1003.我要通过!(20)
题意:判断给出的一段字符串是否满足要求,(1)xPATx,(2)xPAATxx,(3)xPAAATxxx,……满足输出YES,否则NO。
思路 :第一找出规律:(1只能含有PAT,x只能为A组成的字符串或者空字符串,(2顺序,(3 PT之间A的个数与两边x的个数。( 即中间有n个A,则x不为空时,右边必有n个x )。
所以我的思路是
(1)首先在字符串一半长度之前找到 P的位置 ,同时 判断首尾的x 是否满足要求,未找到或不满足要求输出NO,
(2)找到且满足要求,得到x(m个A),再找 T的位置 ,中间是否都是A,未找到或不满足要求,输出NO,
(3)找到且满足要求,得到中间A的个数n,字符串个数为 m*(n+1)+n+2 ;判断个数是否满足要求,不满足输出NO。
(4)个数满足,再看后面的n-1个x是否满足要求,不满足输出NO,满足输出YES。
注意点 :把规律找到,情况考虑全,问题不大;我感觉我的思路有点复杂,因为题目三的要求像递归,可能有更简单的方法。做了三次,前两次是都是未认真分析题意,哎!理解出题人的意图很重要!!!!!!
第一个程序是最开始编写的,考虑的情况明显不够,但好像只有一个测试点未通过。第二个程序全通过了。
#include<stdio.h>    //部分正确??????? 未考虑第三种情况。 
#include<string.h>
void judge(char a[101])
{
	int l=strlen(a);
	if((l-3)%2==0)
	{
		int i=0,ll=l; 
		while(1)
		{
			if(a[i]=='A'&&a[l-i-1]=='A'&&ll>3)
			   ll-=2,i+=1;
			else if(ll==3&&a[i]=='P'&&a[i+1]=='A'&&a[i+2]=='T')
			{
			   printf("YES\n");
			   break;
		    }
			else 
			{ 
			   printf("NO\n");
			   break;
			}
		}
	}
	else if((l-4)%3==0)
	{
		if(l==4&&a[0]=='P'&&a[1]=='A'&&a[2]=='A'&&a[3]=='T')printf("YES\n");
		else 
		{
			int i;
			for(i=0;i<(l-4)/3;i++)
			{
				if(a[i]=='A'&& a[i+(l-4)/3+4]=='A'&&a[i+2*(l-4)/3+4]=='A');
				else break;
			}
			if(i==(l-4)/3&&a[0+i]=='P'&&a[1+i]=='A'&&a[2+i]=='A'&&a[3+i]=='T')printf("YES\n");
			else printf("NO\n");
		}
	}	
	else printf("NO\n");	
}
int main()
{
	int n;
	char str[10][101];
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%s",str[i]);
	for(int i=0;i<n;i++) judge(str[i]); 
    return 0;
}
这个程序是全部通过了的
#include<stdio.h>         
#include<string.h>
void judge(char ch[])
{
	int len=strlen(ch),i=0;
	int ip=0,it=0;
	while(i<=len/2)
	{
		if(ch[i]=='A'&&ch[len-i-1]=='A') i++;   //如果检测到A, 
		else if(ch[i]=='P')   //查找P的位置 
		{
			ip=i,i++;
			while(i<len)
			{
				if(ch[i]=='A')i++;
				else if(ch[i]=='T')  //找到T的位置 
				{
					it=i;
					break;
				}
				else 
				{
					printf("NO\n");
					goto exit;
				}
			}
			if(it==0)  //未找到T 
			{
				printf("NO\n");
				goto exit;
			}
			int a=it-ip-1;  //中间A的个数 
			int b=ip*(a+1)+a+2;   //满足要求的长度 
			if((a==1||(ip==0&&a>0))&&len==b)   //不需要继续检查满足要求的情况 
			{
				printf("YES\n");
				goto exit;
			}
			else if(a>1&&ip>0&&len==b)    //需要继续检查的情况 
			{
				for(int j=it+1;j<=it+(a-1)*ip;j++)
				{
					if(ch[j]!='A')   //不满足要求的情况 
					{
						printf("NO\n");
						goto exit;
					}
				}
				printf("YES\n");
				goto exit;
			}
			else     //其他不满足的情况 
			{
				printf("NO\n");
				goto exit;
			}
		} 
		else
		{
			printf("NO\n");
			goto exit;
		}
    } 
    if(i>len/2)printf("NO\n");   //为找到P 
    exit:;
}
int main()
{
	int n;
	char str[10][101];
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%s",str[i]);
	for(int i=0;i<n;i++) judge(str[i]); 
    return 0;
}
1004.成绩排名 (20)
题意:读入n名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号。
思路:因为只需要输出最高和最低的姓名和学号,所以用一个结构体储存姓名,学号,成绩,然后遍历n名学生,用两个结构体变量min,max储存最低最高学生的姓名,学号,成绩。然后输出就可以了,
注意点不需要排序 。题目未规定人数限制,所以数组取得尽可能大就行了。
#include<stdio.h>    //段错误   数据越界 
struct score{
	char n[11];
	char x[11];
	int  s;
};
int main()
{
	struct score st[10000];
	int N,a=0,b=0;
	scanf("%d",&N);
	for(int i=0;i<N;i++)scanf("%s %s %d",st[i].n,st[i].x,&st[i].s);
	int min=st[0].s,max=st[0].s;
	for(int i=1;i<N;i++)
	{
		if(min>st[i].s)
		{
			min=st[i].s;
			a=i;
		}
		if(max<st[i].s)
		{
			max=st[i].s;
			b=i;		
		}
	}
	printf("%s %s\n",st[b].n,st[b].x);
	printf("%s %s\n",st[a].n,st[a].x);
	return 0;
}
1005.继续(3n+1)猜想 (25)
题意:当一个数n进行卡拉兹(Callatz)猜想时,会得到一组数据,这组数据里的数称为被n 覆盖 关键数 则是一组数据中不被其他数所覆盖的数,找出一组数据中关键数。
思路 :遍历数组,查看一个数是否被其他数所覆盖,若被一个数所覆盖,则检查下一个数,若都不被覆盖,则保存该数。所以设计一个判断一个数是否被另一个数所覆盖的函数。找到给出数据中所有的 关键数 ,然后 排序 ,从大到小输出。
注意点 :思路还是比较清晰的,注意一下细节就行了,如输出格式之类的。
#include<stdio.h>      //注意输出格式 
int judge(int a,int N) //a 是否被N所覆盖 
{
    while(N>1)
       {
            if(N%2)
            {
                N=(3*N+1)/2;
                if(N==a)break;
            }
            else 
            {
                N=N/2;
                if(N==a)break;
            }
       }
       if(N==1)return 0;
       else return 1;
}
int main()
{
    int K,a[100],b[100],s=0;
    scanf("%d",&K);
    for(int i=0;i<K;i++) scanf("%d",&a[i]);
    for(int i=0;i<K;i++)
    {
        int j=0;
        for(int m=0;m<K;m++)
        {
            if(a[i]>0&&a[m]>0&&m!=i&&judge(a[i],a[m]))  //如果a[i]被其他数覆盖 ,将其置为0 
            {
                a[i]=0;
                j++;
                break;
            }
        }
        if(j==0)     //未被覆盖 ,个数加一 
        {
            b[s]=a[i];
            s++;
        }
    }
    for(int i=0;i<s;i++)  //排序 
    {
        for(int k=i+1;k<s;k++)
        {
            if(b[i]<b[k])
            {
                int x;
                x=b[i],b[i]=b[k],b[k]=x;
            }
        }
        printf("%d",b[i]);
        if(i<s-1)printf(" ");  //格式控制,不是最后一个输出空格 
    }
    printf("\n");
    return 0;
}
1006.换个格式输出整数 (15)
题意:给出三位数bsg,输出b个的B,然后输出s个的S,再输出1……g
思路 :得到个十百位上的数值,然后按要求输出,挺简单的。
注意点 :仔细点就行了吧。
#include<stdio.h>
int main()
{
	int n;
	scanf("%d",&n);
	int x;
	x=n/100;
	if(x)
	   for(int i=0;i<x;i++)
	        printf("B");
    x=n%100/10;
	if(x)
	    for(int i=0;i<x;i++)
	        printf("S");
	x=n%100%10;
	if(x)
	    for(int i=1;i<=x;i++)
	        printf("%d",i);
	return 0;
}
1007.素数对猜想 (20)
题意:“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。找出不超过给出数n的素数对的对数。
思路 :从2遍历到n,得到所有素数,再判断相连差为2的素数对的对数,最后输出对数m就行了。
注意点 :为了节约存储空间,只需两个数储存相连素数就行,不需要存小于n的所有素数,这样是以时间复杂度为前提的。
#include<stdio.h>
#include<math.h>
int judge(int n)
{
	int a=sqrt(n)+1;
	if(n>2)
	{
	    for(int i=2;i<a;i++)
		    if(n%i==0)return 0;
	}
	return 1;	
}
int main()
{
	int n,a[2];
	int s=0;
	scanf("%d",&n);
	a[0]=1;
	for(int i=2;i<=n;i++)
	{
		if(judge(i))
		{
			a[1]=i;
			if((a[1]-a[0])==2)s++;
			a[0]=i;
		}
	}
	printf("%d\n",s);
	return 0;
}
1008.数组元素循环右移问题 (20)
题意:将一个数组循环右移,在不允许使用另外数组的前提下,如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?
思路:直接在读入数据时,下标设置不同,将其读入到移动后的位置,虽然不和题意,但结果是对的,
正确的思路
(1)可以创建一个列表,则右移只需要修改最后一个节点的指针和第一个节点的头指针。
(2)若只能用储存为数据形式,可以N=x*M+K,所以用一个a来储存中间变量,当转移个数小于K趟,一趟转移x+1次,大于K时,则x次。然后就只有前M个数位置不对,在调整前面M个位置。所以总的次数为M*K*(x+1)+x*M*(M-K)+M*(M-K)……+2

注意点 :感觉我的思路并不合题意。。。
#include<stdio.h>
int main()
{
    int str[101];
    int n,m;
    scanf("%d %d",&n,&m);
    if(n>m)
    {
        for(int i=m;i<n;i++)scanf("%d",&str[i]);
        for(int i=0;i<m;i++)scanf("%d",&str[i]);
    }
    else if(n==m)
        for(int i=m;i<n;i++)scanf("%d",&str[i]);
    else 
    {
        int x=m%n; 
        for(int i=x;i<n;i++)scanf("%d",&str[i]);
        for(int i=0;i<x;i++)scanf("%d",&str[i]);
    }
    for(int i=0;i<n;i++)
    {
        printf("%d",str[i]);
        if(i<n-1)printf(" ");
    }
    return 0;
}
1009.说反话 (20)
题意:给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
思路 :用gets()得到一行的句子,然后以空格为标记,用递归方式分别输出每个单词,比较方便。
注意点 :单词里的每个单词并不颠倒顺序。

#include<stdio.h>
#include<string.h>
void fx(char s[],int k,int n)
{
	for(int i=k;i<=n;i++)
	{
		if(s[i]==' ')
		{
			fx(s,i+1,n);
			printf(" ");
			for(int j=k;j<i;j++)printf("%c",s[j]);
			break;
		}
		if(i==n)
		    for(int j=k;j<i;j++)printf("%c",s[j]);
	}
}
int main()
{
	char str[81];
	gets(str);
	int n=strlen(str);
	fx(str,0,n);
	return 0; 
 } 
1010.一元多项式求导 (25)
题意:设计函数求一元多项式的导数。(注:xn(n为整数)的一阶导数为n*xn-1。)。指数递降方式
思路 :用一个数组存储,一个存系数,紧接着一个存指数,然后第一个乘以第二个得求导后的第一个,第二个减一得求导后的第二个。
注意点 :注意格式,最后没有空格。注意第二个为0时。求导后第一个也为0。不输出。
#include<stdio.h>
int main()
{
	int a[2000];
	int n=0;
	while(1)
	{
		scanf("%d",&a[n]);
		n++;
		if(getchar()=='\n')break;
	}
	for(int i=0;i<n;i++)
	{
		if(a[i+1])
		{
		   printf("%d ",a[i]*a[i+1]);
		   printf("%d",a[i+1]-1);
		   if(i<n-4||a[n-1]&&i<n-2)printf(" ");
		   i++;
		}
		else if(a[i+1]==0&&n==2)
		{
			printf("0 0");
			break;
		}
	}
	return 0;
}
1011.A+B和C (15)
题意:给定区间[-231, 231]内的3个整数A、B和C,请判断A+B是否大于C。然后按要求输出就行了。
思路 :用一个二维数组存储每行数据ABC,判断是否满足要求,按要求输出结果!
注意点 :仔细一点就行。
#include<stdio.h>
int main()
{
    long num[10][3];    //储存T行,每行3个元素ABC
    int n;
    scanf("%d",&n);
    int i;
    for(i=0;i<n;i++)scanf("%ld %ld %ld",&num[i][0],&num[i][1],&num[i][2]);   //输入ABC
    for(i=0;i<n;i++)
    {
        (num[i][0]+num[i][1])>num[i][2]?printf("Case #%d: true\n",i+1):printf("Case #%d: false\n",i+1);
    }
    return 0; 
}
1012.数字分类 (20)
题意:给定一系列正整数,请按要求对数字进行分类,并按照要求输出5个数字。
思路 :用一个数组存储数据,然后逐个判断该数属于哪类,然后再按要求求每类要输出的值。
注意点 :注意可能为0 的情况和各个数字的判断依据,和输出的格式。

#include<stdio.h>
int main()
{
    int num[1000];
    int i,n;
    scanf("%d",&n);
    for(i=0;i<n;i++)scanf("%d",&num[i]);
    int A[5]={0,0,0,0,0};
    int a1,a3;
    a1=1,a3=0;
    for(i=0;i<n;i++)
    {
        switch(num[i]%5)
        {
            case 0:
                if(num[i]%2==0)A[0]+=num[i];
                break;
            case 1:
                if(a1%2==0)A[1]-=num[i];
                else A[1]+=num[i];
                a1++;
                break;
            case 2:
                A[2]++;
                break;
            case 3:
                A[3]+=num[i];
                a3++;
                break;
            case 4:
                if(num[i]>A[4])A[4]=num[i];
                break;
        }
    }
    if(A[0]==0)printf("N ");
    else printf("%d ",A[0]);
    if(a1==1)printf("N ");             //注意A[1]可能等于0 
    else printf("%d ",A[1]);
    if(A[2]==0)printf("N ");
    else printf("%d ",A[2]);
    if(A[3]==0)printf("N ");
    else printf("%.1f ",(float)A[3]/a3);
    if(A[4]==0)printf("N");
    else printf("%d",A[4]);
    return 0;
}
1013.数素数 (20)
题意:令Pi表示第i个素数。现任给两个正整数M <= N <= 104,请输出PM到PN的所有素数。
思路 :(1)找到第M个素数:从第一个素数2开始,逐个判断自然数是否为素数,是,素数个数加一,找到i=M ;
(2)从第M个素数,重复(1),找素数,并输出,直到找到第N个素数,
注意点 :(1)每满10个要换行,(2)格式,最后一个数后面没有空格。
#include<stdio.h>
#include<math.h>
int ispre(int n)
{
    int i,nn;
    nn=sqrt(n);
    for(i=2;i<=nn;i++)
    {
        if(n%i==0)
           return 0;
    }
    if(i>nn)
        return 1; 
}
int main()
{
    int M,N,i,j,a,num;
    scanf("%d %d",&M,&N);
    i=0,a=2;
    while(i!=M)
    {
        if(ispre(a))i++;    
        a++;
    }
    printf("%d",a-1);      //输出第M个素数 
    if(N==M)return 0;      //N=M结束 
    else
    {
        printf(" ");
        num=1;
        while(i!=N)
        {
            if(ispre(a))
            {
                i++;
                num++;
                printf("%d",a);
                if(num%10){
                    if(i<N)
                       printf(" ");         //注意最后一个没有空格。 
                }
                else printf("\n");
            }
            a++;
        }
    }
    //printf("c");
    return 0;
 }
1014.福尔摩斯的约会 (20)
题意:给出四串字符,根据福尔摩斯解码得到约会的时间。
思路 :(1)用一个数组str[4][61]存储四个字符串,
(2)逐个比较前两个字符串,找到第一个相同的大写字母。得到DAY,作为下标输出对应的字符。
(3)再查找出现第二对相同字符的字符c,作为小时h。截止。
(4)查找后两个字符串,查找出现相同英文字符出现的位置。作为分钟m
注意点 :题意给的不是很清晰,尝试多次后总结的题意意思如下:
第一个是大写字母A-G,第二个是 之后出现 的大写字母A-N或者0-9,第三个是字母就行a-z,A-Z
#include<stdio.h>
//#include<string.h>
#include<ctype.h>
char day[][4]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
int main()
{
    char str[4][61];
    int i,d,h;
    for(i=0;i<4;i++)scanf("%s",str[i]);     //读入四个字符串
    //len=strlen(str[0])>strlen(str[1])?strlen(str[1]):strlen(str[0]); 
    i=0;
    while(1)               //第一个大写字符 
    {
        if(str[0][i]==str[1][i]&&str[0][i]>=65&&str[0][i]<=71)
        {
            d=str[0][i]-65;
            break;
        }
        i++;
    }
    i++;
    while(1)                //第二个字符 
    {
        if(str[0][i]==str[1][i])
        {
            if(str[0][i]>=65&&str[0][i]<=78){
                h=str[0][i]-55;
                break;
            }
            if(isdigit(str[0][i])){
                h=str[0][i]-48;
                break;
            }
        }
        i++;
    }
    i=0;
    while(1)   //分钟 
    {
        if(str[2][i]==str[3][i]&&isalpha(str[2][i]))break;
        i++;
    }
    printf("%s %02d:%02d\n",day[d],h,i);
    return 0;
 }
1015.德才论 (25)21
题意:给一组考生的成绩,将其分为四类,按照给出要求进行排序输出,
思路 :见http://blog.csdn.net/lianwaiyuwusheng/article/details/79134814吧,用链表做的,但有两个测试点超时了21, 以后有新的方法再分享。
注意点 :也就是多注意排序的要求。先是类排序,再是每一类按照要求排序。(总分,德分,准考证号)
#include<stdio.h>  
#include<string.h>  
#include<malloc.h>  
typedef struct{  
    char n[9];       //准考证号  
    int w;            //才   
    int v;            //德   
    int z;  
}stu;  
typedef struct node  
{  
    stu s;  
    struct node *pre;  
    struct node *next;  
}node,*linklist;  
linklist head[4],last[4];  
int L,H;  
int lei(int a,int b)  
{  
    if(a>=H&&b>=H)return 0;  
    if(a>=H)return 1;    //才分不到但德分到  
    if(a>=b)return 2;          //德分不低于才分  
    return 3;  
}  
void Insert(linklist p,int n)  
{  
    linklist q=head[n]->next;  
    while(q!=last[n])  
    {  
        if(q->s.z<p->s.z||(q->s.z==p->s.z&&q->s.v<p->s.v)||(q->s.z==p->s.z&&q->s.v==p->s.v&&strcmp(q->s.n,p->s.n)>0))   //满足需要插入的考生  
        {  
            q->pre->next=p;  
            p->pre=q->pre;  
            p->next=q;  
            q->pre=p;   
            goto exit;  
        }  
        q=q->next;  
    }  
    last[n]->pre->next=p;  
    p->pre=last[n]->pre;  
    p->next=last[n];  
    last[n]->pre=p;  
    exit:;  
}  
int main()  
{  
    int N,i,M;  
    M=0;  
    scanf("%d %d %d",&N,&L,&H);  
    for(i=0;i<4;i++){  
        head[i]=(linklist)malloc(sizeof(node));    //建立四个链表   
        last[i]=(linklist)malloc(sizeof(node));  
        head[i]->next=last[i];  
        last[i]->next=NULL;  
        last[i]->pre=head[i];  
        head[i]->pre=NULL;  
    }  
    for(i=0;i<N;i++)  
    {  
        int a,b,c;  
        char s[9];  
        scanf("%s %d %d",s,&a,&b);  //准考证号、德分、才分  
        if(a>=L&&b>=L)  
        {  
            int le;  
            le=lei(a,b);  
            linklist p;  
            p=(linklist)malloc(sizeof(node));  
            strcpy(p->s.n,s);  
            p->s.v=a;  
            p->s.w=b;  
            p->s.z=a+b;  
            Insert(p,le);  
            M++;  
        }  
    }  
    printf("%d\n",M);  
    for(i=0;i<4;i++)  
    {  
        linklist p;  
        p=head[i]->next;  
        while(p!=last[i])  
        {  
            printf("%s %d %d\n",p->s.n,p->s.v,p->s.w);  
            free(p->pre);  
            p=p->next;  
        }  
        free(last[i]->pre);  
        free(last[i]);  
    }  
    return 0;  
}  
1016.部分A+B (15)
题意:现给定A、DA、B、DB,按照题目规律得到PA和PB,编写程序计算PA + PB。
思路 :我用的字符数组存储AB,比较麻烦,可以用long长整形进行计算,基本都是先得到PA,PB,然后计算PA+PB
注意点 :如果按照我的方法来的话,注意点就比较多了,当DA,DB为0时,得到PA,PB应该为‘0’,而不是‘0000’之类的。还有就是PA,PB的个数问题,进位问题。 还有就是子程序里的字符数组记得赋初值空字符。不然会出现一下意想不到的错误。
#include<stdio.h>
#include<string.h>
void sum(char a[],char b[],int na,int nb)
{
	int n,i;
	char aa[20]={""},bb[20]={""},sum[20]={""};   //记得赋初值,否则会出现不可预测的错误,结果不一致。 
	if(na==0&&nb==0){
	    aa[0]='0';
		bb[0]='0';
		n=1;
	}
	else if(na>nb)
	{
		for(i=0;i<na-nb;i++)bb[i]='0';
		strcat(aa,a);
		strcat(bb,b);
		n=na;
	}
	else
	{
		for(i=0;i<nb-na;i++)aa[i]='0';
		strcat(aa,a);
		strcat(bb,b);
		n=nb;
	}
	int jw;
	jw=0;
	for(i=n-1;i>=0;i--)
	{
		sum[i]=aa[i]+bb[i]+jw-48*2;
		if(sum[i]>9){
		    sum[i]+=38;
			jw=1;
		}
		else {
		    sum[i]+=48;
		    jw=0;
		}
	}
	if(jw)printf("%d",jw);
	printf("%s",sum);
}
int main()
{
	char A[20],B[20],pa[20],pb[20];
	int da,db,i,na,nb;
	scanf("%s %d %s %d",A,&da,B,&db);
	na=0,nb=0;
	if(da)           //当Da与Db为0时要注意,PA=0而不是Pa=0000. 
	{
	    for(i=0;i<strlen(A);i++)
	    {
		    if(A[i]==(da+48))
		    {
		        pa[na]=da+48;
			   na++;
		    }
		}
	}
	else na=1,pa[0]='0';
	if(db)
	{
	for(i=0;i<strlen(B);i++)
	{
	    if(B[i]==(db+48))
	    {
		    pb[nb]=db+48;
			nb++;
		}
	} 
    }
    else nb=1,pb[0]=0;
	sum(pa,pb,na,nb);
	return 0;
 } 
1017 A除以B (20)
题意:一个最大1000位的数除以一位整数,求商与余。
思路:除数只是一位数,变简单了,除法总是除得余数加上后面的余数,再除,直到除到最后一位。所以商为逐个求得的商,余数为最后一次求得的余数,
注意点:首先应该判断被除数的位数,即是否为最后一次除法运算。
#include<stdio.h>
#include<string.h>
int main()
{
	char num[1000];
	int B,A,n,i;
	scanf("%s %d",num,&B);
	i=0;
	n=strlen(num);
	A=(num[0]-'0');
	if(n>1)
	{
	    while(n>1)
	    {
		    i++;
		    A=A*10+num[i]-'0';
		    printf("%d",A/B);
		    A=A%B;
		    n--;
	    }
	    printf(" %d",A);
    }
    else printf("%d %d",A/B,A%B);
    return 0;
 } 
1018 锤子剪刀布 (20)
题意:根据石头剪刀布的规则,判断两个人的赢输平的情况,和获胜次数最多的手势。
思路:可能出现的情况为9种,3种为平局,根据每一次输入判断甲乙获胜(以何种方式获胜)、平、输的次数。输入结束后根据记录,输出每个人输赢平的次数,并输出获胜次数最多的手势。

注意点:规则简单,情况较少,用最笨的方法考虑每一种情况就行。也许用更简单的办法,欢迎在评论区留言。

#include<stdio.h>
typedef struct{
	int w1;
	int w2;
	int w3;
}win;
struct qk{
	win w;
	int e;
	int l;
}j={0,0,0,0,0},y={0,0,0,0,0};
void judge(char a,char b)
{
	if(a==b)
	{
		j.e++;
		y.e++;
	}
	else
	{
		switch(a)
		{
			case 'C':
				switch(b)
				{
					case 'J':        //甲锤子,乙剪刀 ,甲赢 
						j.w.w1++;
						y.l++;
						break;
					case 'B':        //甲锤子,乙布,乙赢 
						y.w.w3++;
						j.l++;
						break;
				}
				break;
			case 'J':
				switch(b)
				{
					case 'C':          //甲剪刀,乙锤子,乙赢 
						y.w.w1++;
						j.l++;
						break;
					case 'B':           //甲剪刀,乙布,甲赢 
						j.w.w2++;
						y.l++;
						break;
				}
				break;
			case 'B':
			    switch(b)
				{
					case 'C':          //甲布,乙锤子,甲赢 
						j.w.w3++;
						y.l++;
						break;
					case 'J':           //甲布,乙剪刀,乙赢 
						y.w.w2++;
						j.l++;
						break;
				}
				break;
		}
	}
	
}
char wch(win a)
{
	if(a.w1>a.w2&&a.w1>a.w3)return 'C';
	if(a.w1>a.w3&&a.w1==a.w2)return 'C';
	if(a.w2>a.w1&&a.w2>a.w3)return 'J';
	if(a.w3>=a.w1&&a.w3>=a.w2)return 'B';
}
int main()
{
	int N;
	scanf("%d",&N);
	getchar(); 
	while(N)
	{
		char a,b;
		scanf("%c %c",&a,&b);
		getchar();
		judge(a,b);
		N--;
	}
	printf("%d %d %d\n",j.w.w1+j.w.w2+j.w.w3,j.e,j.l);
	printf("%d %d %d\n",y.w.w1+y.w.w2+y.w.w3,y.e,y.l);
	printf("%c %c\n",wch(j.w),wch(y.w));
	return 0;
} 
1019 数字黑洞 (20)
题意:
思路:
注意点:

#include<stdio.h>
int a[4];
void sz(int n)
{
	int i=3;
	while(i>=0)
	{
		a[i]=n%10;
		n=n/10;
		i--;
	}
}
int px(int b,int x)
{
	int i,j,n;
	n=0;
	sz(b);
	if(x==1)    //非增排序 
	{
	    for(i=0;i<4;i++)
    	{
		    for(j=i+1;j<4;j++)
	    	{
			    if(a[j]>a[i])
			    {
				    int t;
			    	t=a[i];
			    	a[i]=a[j];
			    	a[j]=t;
			    }
		   }
		n=n*10+a[i];
	    }
	}
	else     //非减排序 
	{
		for(i=0;i<4;i++)
    	{
		    for(j=i+1;j<4;j++)
	    	{
			    if(a[j]<a[i])
			    {
				    int t;
			    	t=a[i];
			    	a[i]=a[j];
			    	a[j]=t;
			    }
		   }
		n=n*10+a[i];
	    }
	}
	return n;
}
int main()
{
	int n,i;
	scanf("%d",&n);
	//for(i=0;i<4;i++)printf("%d",a[i]);
	sz(n);
	if(a[0]==a[1]&&a[1]==a[2]&&a[2]==a[3])printf("%04d - %04d = 0000\n",n,n);
	else
	{
		do
		{
			int temp;
			temp=px(n,1)-px(n,0);
			printf("%04d - %04d = %04d\n",px(n,1),px(n,0),temp);
			n=temp;
		}while(n!=6174);
	}
	return 0;
 } 
1020 月饼 (25)
题意:

思路:

注意点:数据类型吧

#include<stdio.h>
typedef struct{    //注意不一定是整数 
	float kc;
	float sj;
}zlei;
int main()
{
	int n,num,i,j;
	zlei z[1000];
	scanf("%d %d",&n,&num);
	for(i=0;i<n;i++)scanf("%f",&z[i].kc);
	for(i=0;i<n;i++)scanf("%f",&z[i].sj);  //数据类型改了,后面的控制也要改。 
	for(i=0;i<n;i++)             //排序 
	{
		zlei temp;
		for(j=i+1;j<n;j++)
		{
			if(z[i].sj/z[i].kc<z[j].sj/z[j].kc)
			{
				temp=z[i];
				z[i]=z[j];
				z[j]=temp;
			}
		}
	}
	i=0;
	float sum;
	sum=0;
	while(1)
	{
		if(num>z[i].kc)
		{
			sum+=z[i].sj;
			num-=z[i].kc;
			i++;
		}
		else 
		{
		    sum+=num*z[i].sj/z[i].kc;
		    break;
		}
	}
	printf("%.2f\n",sum);
	return 0;
 } 
1021  个位数统计 (15)
题意:

思路:

注意点:

#include<stdio.h>
#include<string.h>
int main()
{
	char ch[1000];
	int N[10]={0};
	scanf("%s",&ch);
	for(int i=0;i<strlen(ch);i++)
	   N[ch[i]-48]++;
	for(int i=0;i<10;i++)
	{
		if(N[i])
		  printf("%d:%d\n",i,N[i]);
	}
	return 0;
}
1022 D进制的A+B (20)
题意:

思路:

注意点:

#include<stdio.h>
int o;
void jz(long a)
{
	if(a/o==0)
	    printf("%ld",a%o);
	else
	{
	    jz(a/o);
	    printf("%ld",a%o);
	}
}
int main()
{
	long a,b,c;
	scanf("%ld %ld %d",&a,&b,&o);
	c=a+b;
	jz(c);
	return 0;
}
1023 组个最小数 (20)
题意:

思路:

注意点:

#include<stdio.h>
int main()
{
	int a[10]={0},i,j;
	char c,b;
	for(i=0;i<10;i++)scanf("%d",&a[i]);
	i=1;
	while(1)
	{
		if(a[i])          //输出最小的非0元素 
		{
		    printf("%d",i);
		    a[i]--;
		    break;
		}
		i++;
		if(i==10)           //当非0个数都为0时 
		{
		    printf("0\n");
		    return 0;
		}
	}
	for(i=0;i<10;i++)
	{
		for(j=0;j<a[i];j++)
		    printf("%d",i);
	}
	printf("\n");
	return 0;
}
1024 科学计数法 (20)
题意:
思路:
注意点:
#include<stdio.h>
#include<string.h>
int main()
{
	char str[10000];
	int i,ex,tag,n;
	gets(str);
	if(str[0]=='-')printf("-");
	i=3;
	while(str[i]!='E') 
	{
		i++;
	}
	ex=i;//指数位置 
	if(str[i+1]=='+')tag=1;
	else tag=0;
	n=0;
	for(i=ex+2;i<strlen(str);i++)n=n*10+str[i]-'0';//指数值
	if(n==0)     //指数为0 
	{
	    for(i=1;i<ex;i++)
	    	printf("%c",str[i]);
	    return 0;
	}
	if(tag==0)  //小数点左移 
	{
		printf("0.");
		for(i=0;i<n-1;i++)printf("0");
		printf("%c",str[1]);
		for(i=3;i<ex;i++)printf("%c",str[i]);
	} 
	else  //小数点右移 
	{
		int xx; 
		for(i=1;i<ex;i++)// 第一个非零数的位置 
		{
			if(str[i]>'0'&&str[i]<='9')
			{
				xx=i;
				break;
			}
		} 
		if(n<ex-3)//指数小于小数位数 
		{
			i=xx>n+2?n+2:xx;
			for(i;i<ex;i++)
			{
				if(i!=2)
				{
					printf("%c",str[i]);
					if(i==n+2)printf(".");
				}
			} 
		}
		else   //指数大于小数位数 
		{
			for(i=xx;i<ex;i++)
			{
				if(i!=2)
			        printf("%c",str[i]);
			}
			for(i=0;i<n-ex+3;i++)printf("0");
		}
	}
	return 0;
}
1025 反转链表 (25)0
题意:

思路:

注意点:反转的时候思路是错的,,,,,,错的思路值得引以为戒

#include<stdio.h>           //错 
#include<malloc.h>
typedef struct{
	int add;
	int data;
	int n_add;
}ele; 
typedef struct node{
	ele n;
	struct node *pre;
	struct node *next;
}node,*linklist;
linklist head;
int main()
{
	int i,j,N,M;
	ele a[100000];
	head=(linklist)malloc(sizeof(node));
	head->pre=NULL;
	scanf("%d %d %d",&head->n.n_add,&N,&M);
	for(i=0;i<N;i++)         //读入节点数据 
		scanf("%d %d %d",&a[i].add,&a[i].data,&a[i].n_add);
	linklist q,x,p=head;
	for(i=0;i<N;i++)    //生成链表 
	{
		j=0;
		while(p->n.n_add!=a[j].add)
		{
			j++;
		}
		q=(linklist)malloc(sizeof(node));
		q->n=a[j];
		p->next=q;
		q->pre=p;
		p=q;
	} 
	p=head->next;
	for(i=1;i<=N;i++)           //反转链表 
	{
		if(i%M==0)
		{
			x=p;
			q=p;
			for(j=1;j<M;j++)
			{
				printf("%05d %d %05d\n",q->n.add,q->n.data,q->pre->n.add);
				q=q->pre;
			}
			if(x->n.n_add!=-1)
		        printf("%05d %d %05d\n",q->n.add,q->n.data,x->n.n_add);
		    else
		        printf("%05d %d %d\n",q->n.add,q->n.data,x->n.n_add);
		}
		p=p->next;
	}
	while(x->n.n_add!=-1)
	{
		x=x->next;
		if(x->n.n_add!=-1)
		    printf("%05d %d %05d\n",x->n.add,x->n.data,x->n.n_add);
		else
		    printf("%05d %d %d\n",x->n.add,x->n.data,x->n.n_add);
	}
	return 0;
}

1026 程序运行时间(15)
题意:

思路:

注意点:

#include<stdio.h>
int main()
{
	long c1,c2,sj;
	scanf("%ld %ld",&c1,&c2);
	sj=(c2-c1+50)/100;           //四舍五入 
	printf("%02ld:%02ld:%02ld",sj/60/60,sj/60%60,sj%60);
	return 0;
}
1027 打印沙漏(20)
题意:

思路:

注意点:

#include<stdio.h>   //部分正确????????
#include<math.h>    //无论是否剩余,都要输出剩余数。。。。。加判断输入是否满足要求???
int main()
{
  int N,n;
  char ch;
  scanf("%d %c",&N,&ch);
  n=sqrt((N+1)/2);
  for(int i=n;i>=-n;i--)
  {
    for(int j=1;j<=n-abs(i);j++)
      printf(" ");
    for(int j=1;j<=2*abs(i)-1;j++)
      printf("%c",ch);
    printf("\n");
    if(i==1)      //当i减到1时跳到-1
      i-=2;
  }
  //if(N-2*n*n+1 && N)
     printf("%d\n",N-2*n*n+1);
  return 0;
}
1028 人口普查(20)
题意:判断给定出生年月是否合法,并计算个数,找出年级最大和最小的人。

思路:假设最大年级出生年月2014/9/6.最小为1814/9/6.判断是否合法,再与最大最小年级判断,修改最大最小姓名和出生年月。最后输出合法人数及最大最小人。

注意点:输出合法人数为0,此时格式为0。把合法情况考虑完全问题不大。

#include<stdio.h>
typedef struct{
	char name[6];
	int year;
	int mouth;
	int day;
}people;
int main()
{
	int n,i,m;
	people peo,min={"",1814,9,6},max={"",2014,9,6};
	scanf("%d",&n);
	m=0;
	for(i=0;i<n;i++)
	{
		scanf("%s %d/%d/%d",peo.name,&peo.year,&peo.mouth,&peo.day);
		if(peo.year<2014&&peo.year>1814||(peo.year==2014&&peo.mouth<9)||(peo.year==1814&&peo.mouth>9)||(peo.year==2014&&peo.mouth==9&&peo.day<=6)||(peo.year==1814&&peo.mouth==9&&peo.day>=6))
		{
			m++;
			if(peo.year>min.year||(peo.year==min.year&&peo.mouth>min.mouth)||(peo.year==min.year&&peo.mouth==min.mouth&&peo.day>min.day))min=peo;
			if(peo.year<max.year||(peo.year==max.year&&peo.mouth<max.mouth)||(peo.year==max.year&&peo.mouth==max.mouth&&peo.day<max.day))max=peo;
		}
    }
    if(m)printf("%d %s %s",m,max.name,min.name);
    else printf("0");
    return 0;
 } 
1029    旧键盘(20)

题意:

思路:

注意点:

#include<stdio.h>
int main()
{
	char str1[81];
	char str2[81];
	char out[81]={""};
	gets(str1);
	gets(str2);
	int i=0,j=0,n=0,x;
	while(str1[i]!='\0')
	{
		if(str1[i]==str2[j])
		{
			i++;
			j++;
		}
		else
		{
			if(str1[i]<123&&str1[i]>96)//小写字母  
			    str1[i]=str1[i]-32;
			for(x=0;x<n;x++)
			{
				if(out[x]==str1[i]) goto next;
			}
			out[n]=str1[i];
			n++;
			next:i++;
		}
	}
	puts(out);
}
1030   完美数列(25)

题意:

思路:

注意点:

#include<stdio.h>
#include<malloc.h>
typedef struct node{
	long d;
	struct node *pre;
	struct node *next;
}node,*linklist;
linklist head,last;
int main()
{
	int n,i,M;
	long P,m,a;
	scanf("%d %ld",&n,&P);  //忘记为head和last开空间了。
	head=(linklist)malloc(sizeof(node));
	last=(linklist)malloc(sizeof(node)); 
	head->pre=NULL;
	head->next=last;
	last->pre=head;
	last->next=NULL;
	linklist q,p;
	for(i=0;i<n;i++)
	{
		scanf("%ld",&a);
		q=(linklist)malloc(sizeof(node));
		q->d=a;
		p=head->next;
		while(p!=last)
		{
			if(a<p->d)    //需要插入 
			{
				p->pre->next=q;
				q->pre=p->pre;
				q->next=p;
				p->pre=q;
				goto next;
			}
			p=p->next;
		}
		p->pre->next=q;
		q->next=p;
		q->pre=p->pre;
		p->pre=q;
		next:;
	}
	p=head->next;
	M=0;
	while(p!=last)
	{
	    m=p->d;
	    i=0;
	    q=p;
	    while(P*m>=q->d&&q!=last)   //注意个数,如果与下一个比较,则个数需要加一。 //需要判断链表是否超出 
	    {
		    i++;
		    q=q->next;
		}
		if(M<i)M=i;
		p=p->next; 
	}
	printf("%d",M);
	return 0;
}
1031 查验身份证(15)
题意:

思路:

注意点:

#include<stdio.h>
#include<string.h>
int w[]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
char M[]={'1','0','X','9','8','7','6','5','4','3','2'};
int judge(char str[])
{
	int x,i;
	x=0;
	for(i=0;i<17;i++)
	{
		if(str[i]>=48&&str[i]<58)
		{
		    x+=(str[i]-48)*w[i];
	    }
		else return 0;    //假 
	}
	if(M[x%11]==str[17])return 1;  //低级错误,!!!!!!!!!!!!! 
	else return 0;
}
int main()
{
	int n,i,m;
	char str[19],out[100][19];
	scanf("%d",&n);
	getchar();
	m=0;
	for(i=0;i<n;i++)
	{
		//getchar();
		gets(str);
		if(judge(str)==0)    //假 
		{
			strcpy(out[m],str);
			m++;
		}
	}
	if(m==0)printf("All passed\n"); 
	else 
	{
	   // printf("%d\n",m);
	    for(i=0;i<m;i++)printf("%s\n",out[i]);
	}
	return 0;
}
1032 挖掘机技术哪家强(20)
题意:

思路:

注意点:不严谨

#include<stdio.h>
int main()
{
	int n,i,a,b;
	int s[100000]={0};
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d %d",&a,&b);
		s[a]+=b;
	}
	for(i=0;i<n;i++)
	{
		if(b<s[i])
		{
		    b=s[i];
		    a=i;
		}
	}
	printf("%d %d",a,b);
	return 0;
}
1033 旧键盘打字(20)
题意:

思路:

注意点:16分,我也不知道错哪了????????

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
	char str1[100],str2[100000];
	int i,j,n,flag;
	gets(str1);
	n=strlen(str1);
	for(i=0;i<n;i++)
	{
		//if(str1[i]==' ')str1[i]='_';
		if(str1[i]=='+')
		{
			flag=1;
			break;
		}
	}
	gets(str2);
	i=0;
	while(str2[i]!='\0')
	{
		if(flag)
		{
			if(isupper(str2[i]))goto next;
		}
		for(j=0;j<n;j++)
		{
			if(str1[j]==str2[i])goto next;
			if(((str2[i]-32)==str1[j])&&str2[i]>=97&&str2[i]<=122)goto next;
		}
		putchar(str2[i]);
		next:i++;
	}
	printf("\n");
	return 0;
}
1034 有理数四则运算(20)
题意:

思路:

注意点:超时了,可能是求公约数花费时间太多?输出操作数是可以不需要每次都重新调用函数进行输出。

#include<stdio.h>           //数据用长整形,可能数据范围超出,从而错误 
char c[]={'+','-','*','/'};
int gy(long a,long b)
{
	long t;
	if(a==b)return a;
	do
	{
		if(b>a)
	    {
		   t=a;
		   a=b;
		   b=t;
    	}
		a=a-b;
	}while(a!=b);
	return b;;
}
void pri(long a,long b)
{
	int flag=2;
	if(a==0)
	{
		printf("0");
	}
	else
	{
		if(a<0)
		{
			a=-a;
			flag++;
		}
		if(b<0)
		{
		    flag++;
		    b=-b;
		}
		int x;
		x=gy(a,b);
		a/=x;
		b/=x;
		if(a/b)
		{
			if(flag%2)
		    {
			    printf("(-%ld",a/b);
			    if(a%b)printf(" %ld/%ld)",a%b,b);
		        else printf(")");
			}
			else
			{
				printf("%ld",a/b);
			    if(a%b)printf(" %ld/%ld",a%b,b);
			}
		}
		else
		{
			if(flag%2)
				printf("(-%ld/%ld)",a,b);
			else
			    printf("%ld/%ld",a,b);
		}
	}
}
int main()
{
	long a1,b1,a2,b2,i;
	scanf("%ld/%ld %ld/%ld",&a1,&b1,&a2,&b2);
	for(i=0;i<4;i++)
	{
		pri(a1,b1);
		printf(" %c ",c[i]);
		pri(a2,b2);
		printf(" = ");
		switch(i)
		{
			case 0:
				pri(a1*b2+a2*b1,b1*b2);
				break;
			case 1:
				pri(a1*b2-b1*a2,b1*b2);
				break;
			case 2:
				pri(a1*a2,b1*b2);
				break;
			case 3:
				if(a2==0)printf("Inf");
				else pri(a1*b2,a2*b1);
		}
		printf("\n");
	}
	return 0;
}
暂时就这么多了,很多有错,我该多看点书了,。。。。。。。渣
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值