题目链接: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储存最低最高学生的姓名,学号,成绩。然后输出就可以了,
思路:因为只需要输出最高和最低的姓名和学号,所以用一个结构体储存姓名,学号,成绩,然后遍历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
(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)找到第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
(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;
}
暂时就这么多了,很多有错,我该多看点书了,。。。。。。。渣