东华大学计算机研究生复试题
71 发牌
题目描述:编制一个模拟发牌的程序。有编号为1,2,3,4四个人,将一付去掉大小怪的扑克按照如下顺序排列梅花c0-c12,方块d0-d12,红桃h0–h12,黑桃s0-s12,然后按照1,2,3,4四个人的顺序发牌,问最后每个人手上的牌有哪些。
思路:每次先输出第一章牌的花色和序号【梅花】】,输出一次就累加4,若数字大于12,则取模,发另一种类型的牌,直到发完13张
#include<stdio.h>
//每个人都是隔4次发一张,可以用num表示牌的数字,直接输出发的牌的花色和编号
//输出一次num累加4,若num>12,则num%13,因为每人有有13张,花色更新一下就OK了,总共输出十三次
int main()
{
int i=0;//统计已发的牌的张数
int num=0;//当前牌的数字
int count=0;//统计换花色的次数
int pernum=0;//人员编号
char patterns[6]="cdhs";
char ch=patterns[count];///当前牌的花色
while(scanf("%d",&pernum)!=EOF)
{
//重置数据
i=0;
num=pernum-1;
count=0;
ch=patterns[count];
//先输出第一个
printf("c %d",num);
i++;//已经发了一张牌了
while(i<13)
{
//需要发13次
num+=4;
if(num>12)
{
num%=13;
//换花色
ch=patterns[++count];
printf(" %c %d",ch,num);
}
else
{
//不用换花色
printf(" %c %d",ch,num);
}
i++;//又发了一张
}
printf("\n");
}
return 0;
}
72 数字金字塔
题目描述:考虑在下面被显示的数字金字塔(第n行有n列)。写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大。每前进一步可以走到它的正下方或者右下方(往下一行、往右一列)的位置。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的样例中,从7 到 3 到 8 到 7 到 5 的路径产生了最大和:30
思路:这不就是和二叉树求高类似吗
#include<iostream>
using namespace std;
#define MAXN 1000
int arr[MAXN][MAXN]={0};
//每一条分岔都是一条二叉树路径,按照二叉树求高的方式进行求解
int solve(int i,int j,int n) {
//边界条件,超出范围都为0
if (i >= n || j >= n)return 0;
int left = solve(i + 1, j, n); //左子树
int right = solve(i + 1, j + 1, n); //右子树
//二叉树求高时加1,此时加自身值
return arr[i][j] + max(left, right);
}
int main() {
int n;
//输入行的数目
cin >> n;
//输入数字金字塔内容
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++)cin >> arr[i][j];
}
//调用函数得出答案
cout << solve(0, 0, n);
}
//求二叉树的高度
//int getTreeHigh(Node* root) {
// if (root == NULL) return 0;
// int left_high = getTreeHigh(root->lchild);
// int right_high = getTreeHigh(root->rchild);
// return max(left_high, right_high) + 1;
//}
73 稀疏矩阵
题目描述:明明的问题可以归结为:试编程将一个稀疏矩阵a转换成只存放非零元素的矩阵b,即找出每个不是0的元素,按从左到右从上到下的顺序,输出其所在的行和列以及它的值。
思路:双重循环直接遍历,如果不为0,则输出位置和值
/*
T61 稀疏矩阵
*/
#include<stdio.h>
#define MAX_SIZE 20
int main() {
int M = 0, N = 0;
int matrix[MAX_SIZE][MAX_SIZE] = {0};
int i = 0, j = 0;
while (scanf("%d%d", &M, &N) != EOF) {
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
scanf("%d", &matrix[i][j]);
}
}
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
if (matrix[i][j] != 0) {
printf("%d %d %d\n", i + 1, j + 1, matrix[i][j]);
}
}
}
printf("\n");
}
return 0;
}
74 矩阵转换
题目描述:明明的问题可以归结为:有一个r×r的矩阵,把矩阵中的数以左上到右下的对角线的方式进行转换,然后输出转换后的矩阵。
思路:直接把输出a[i][j]变成a[j][i]就行了,不需要将对角线的元素进行转换
#include<stdio.h>
int main()
{
int n;
int i,j;
while(~scanf("%d",&n))
{
int a[10][10];
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(j<n-1)//注意最后一个元素不能是空格
printf("%d ",a[j][i]);
else
printf("%d\n",a[j][i]);
}
printf("\n");
}
return 0;
}
75 魔方阵
好难,不想做😭
76 最大效益
题目描述:明明的爸爸的问题可以归结为:给你一张5行5列的效益表,表中的数字均为大于等于0的整数,要求在这张表中选出5个数字,使这5个数字的和最大。(注:这5个数字分别来自表中的不同行不同列,即同一行只能选择一个数字,同一列也只能选择一个数字。)
思路:三层循环,最外层遍历选出5个数字,内两层遍历二维数组。首先选出目前最大的数字且该行和列没有元素被选,选择该元素,将该元素的行和列标记,表示已选,此时已经选出了一位数字,接着按同样的方式选出剩余4个数字,使得这5个数字之和最大。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int temp,i,j,row,col,transfer[5][5],max=0,sum=0,k=0,flag[5][5];
while(scanf("%d",&transfer[0][0])!=EOF){
for(i=0;i<5;i++){
for(j=0;j<5;j++){
if(i==0&&j==0){//上面已输入
continue;
}
flag[i][j]=0;//标记是否被选,若被选,则令该数字所在行和列为-1
scanf("%d",&transfer[i][j]);
}
}
for(k=0;k<5;k++){
max=0;//查找最大值
for(i=0;i<5;i++){
for(j=0;j<5;j++) {
if(flag[i][j]!=-1){//若该行和列没有被选
if(transfer[i][j]>max){
max=transfer[i][j];//更新最大值和记录其行和列
row=i;
col=j;
}
}
}
}
sum+=max;//求和
for(i=0;i<5;i++){//对row行,col列全部元素赋值为-1,表示该行列已选
flag[row][i]=-1;
flag[i][col]=-1;
}
}
printf("%d\n",sum);
sum=0;
}
return 0;
}
77 螺旋方阵
题目描述:明明在上学的时候,参加数学兴趣班。在班上,老师介绍了一种非常有趣的方阵,称之为螺旋方阵。该方阵一共由n×n个正整数构成(我们称之为n阶螺旋方阵),即共有n行n列。
方阵中的数字从1开始递增,数字的排序规则是从左上角出发由1开始排序,并按顺时针方向旋进,即先排最外面的一圈,然后排里面的一圈,以此类推,直到排到最后一个数为止。
例如一个4阶的螺旋方阵,一共有4×4=16个正整数构成,数字从1递增到16,最后排出来的方阵如下:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
明明回家后想自己动手构造这样的螺旋方阵。他从n=1开始构造,但是他发现当n越来越大时,螺旋方阵的复杂性就越高,然后构造出来的方阵就越容易出错。为了降低构造方阵的出错率,提高构造速度,明明就求助于你,请你帮他写一个程序,来构造螺旋方阵。 明明的问题可以归结为:给你一个正整数n,请你按题目描述中所述的方法,构造出n阶的螺旋方阵。
思路:按照从左往右,从上往下,从右往左,从下往上的顺序构造
//数组下标从1开始
#include<stdio.h>
int a[10][10];
int main()
{
int n;
int k;//每次循环成功++k
int count=0;
int x,y,i,j;
while(scanf("%d",&n)!=EOF)
{
count++;
if (count > 1)
printf("\n");
k=1;
x=1;
y=0;
while(k<n*n)
{
while(y<n&&a[x][y+1]==0)
{
a[x][++y]=k++;//从左往右
}
while(x<n&&a[x+1][y]==0)
{
a[++x][y]=k++;//从上往下
}
while(y>1&&a[x][y-1]==0)
{
a[x][--y]=k++;//从右往左
}
while(x>1&&a[x-1][y]==0)
{
a[--x][y]=k++;//从下往上
}
}
//格式化输出
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(j==1)
{
printf("%d",a[i][j]);
}
else
{
printf(" %d",a[i][j]);
}
}
printf("\n");
}
}
return 0;
}
78 方块转换
一块N x N(1=<N<=10)正方形的黑白瓦片的图案要被转换成新的正方形图案。
写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式:
#1:转90度:图案按顺时针转90度。
#2:转180度:图案按顺时针转180度。
#3:转270度:图案按顺时针转270度。
#4:反射:图案在水平方向翻转(形成原图案的镜像)。
#5:组合:图案在水平方向翻转,然后按照#1-#3之一转换。
#6:不改变:原图案不改变。
#7:无效转换:无法用以上方法得到新图案。
如果有多种可用的转换方法,请选择序号最小的那个。
注意:图案中的字符“@”和“-”在转90度后,还是“@”和“-”。不要认为“-”转90度后变成“|”
/*
T62 方块转换
算法概述:通过比较两个图案内的符号是否满足坐标变换后的对应关系即可
*/
#include<stdio.h>
#include<string.h>
#define MAX_SIZE 12
typedef struct Icons {
char iconStr[MAX_SIZE];
} Icons;
int isCaseOne(Icons iconsFir[], Icons iconsSec[], int n);
int isCaseTwo(Icons iconsFir[], Icons iconsSec[], int n);
int isCaseThree(Icons iconsFir[], Icons iconsSec[], int n);
int isCaseFour(Icons iconsFir[], Icons iconsSec[], int n);
int isCaseFive(Icons iconsFir[], Icons iconsSec[], int n);
int isCaseSix(Icons iconsFir[], Icons iconsSec[], int n);
int main() {
int N = 0;
int i = 0, j = 0;
Icons iconsFir[MAX_SIZE];
Icons iconsSec[MAX_SIZE];
char temp[MAX_SIZE];
scanf("%d", &N);
for (i = 1; i <= N; i++) {
scanf("%s", iconsFir[i].iconStr);
// 加字符
j = 0;
strcpy(temp, iconsFir[i].iconStr);
iconsFir[i].iconStr[j++] = '#';
while (j < strlen(temp) + 1) {
iconsFir[i].iconStr[j] = temp[j - 1];
j++;
}
iconsFir[i].iconStr[j] = '\0';
}
for (i = 1; i <= N; i++) {
scanf("%s", iconsSec[i].iconStr);
// 加字符
j = 0;
strcpy(temp, iconsSec[i].iconStr);
iconsSec[i].iconStr[j++] = '#';
while (j < strlen(temp) + 1) {
iconsSec[i].iconStr[j] = temp[j - 1];
j++;
}
iconsSec[i].iconStr[j] = '\0';
}
// 分别检测是哪种情况
if (isCaseOne(iconsFir, iconsSec, N)) {
printf("1\n");
return 0;
}
if (isCaseTwo(iconsFir, iconsSec, N)) {
printf("2\n");
return 0;
}
if (isCaseThree(iconsFir, iconsSec, N)) {
printf("3\n");
return 0;
}
if (isCaseFour(iconsFir, iconsSec, N)) {
printf("4\n");
return 0;
}
if (isCaseFive(iconsFir, iconsSec, N)) {
printf("5\n");
return 0;
}
if (isCaseSix(iconsFir, iconsSec, N)) {
printf("6\n");
return 0;
}
printf("7\n");
return 0;
}
// 判断是否满足第一种情况
int isCaseOne(Icons iconsFir[], Icons iconsSec[], int n) {
int i = 0, j = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (iconsFir[i].iconStr[j] != iconsSec[j].iconStr[n + 1 - i]) {
return 0;
}
}
}
return 1;
}
// 判断是否满足第二种情况
int isCaseTwo(Icons iconsFir[], Icons iconsSec[], int n) {
int i = 0, j = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (iconsFir[i].iconStr[j] != iconsSec[n + 1 - i].iconStr[n + 1 - j]) {
return 0;
}
}
}
return 1;
}
// 判断是否满足第三种情况
int isCaseThree(Icons iconsFir[], Icons iconsSec[], int n) {
int i = 0, j = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (iconsFir[i].iconStr[j] != iconsSec[n + 1 - j].iconStr[i]) {
return 0;
}
}
}
return 1;
}
// 判断是否满足第四种情况
int isCaseFour(Icons iconsFir[], Icons iconsSec[], int n) {
int i = 0, j = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (iconsFir[i].iconStr[j] != iconsSec[i].iconStr[n + 1 - j]) {
return 0;
}
}
}
return 1;
}
// 判断是否满足第五种情况(可利用前三种情况)
int isCaseFive(Icons iconsFir[], Icons iconsSec[], int n) {
int i = 0, j = 0;
Icons mirrorFir[MAX_SIZE];// 存放第一个图案的镜面
for (i = 0; i < MAX_SIZE; i++) {
strcpy(mirrorFir[i].iconStr, "a");
}
for (i = 1; i <= n; i++) {// 生成镜面图案
for (j = 1; j <= n; j++) {
mirrorFir[i].iconStr[n + 1 - j] = iconsFir[i].iconStr[j];
}
mirrorFir[i].iconStr[j] = '\0';
}
// 判断生成镜面之后是不是前三种情况中的一种
if (isCaseOne(mirrorFir, iconsSec, n) == 1)
return 1;
if (isCaseTwo(mirrorFir, iconsSec, n) == 1)
return 1;
if (isCaseThree(mirrorFir, iconsSec, n) == 1)
return 1;
return 0;
}
// 判断是否满足第六种情况
int isCaseSix(Icons iconsFir[], Icons iconsSec[], int n) {
int i = 0, j = 0;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (iconsFir[i].iconStr[j] != iconsSec[i].iconStr[j]) {
return 0;
}
}
}
return 1;
}
80 饲料调配
题目描述:农夫约翰从来只用调配得最好的饲料来为他的奶牛。
饲料用三种原料调配成:大麦,燕麦和小麦。他知道自己的饲料精确的配比,在市场上是买不到这样的饲料的。他只好购买其他三种混合饲料(同样都由三种麦子组成),然后将它们混合,来调配他的完美饲料。
给出三组整数,表示 大麦:燕麦:小麦 的比例,找出用这三种饲料调配 x:y:z 的饲料的方法。
例如,给出目标饲料 3:4:5 和三种饲料的比例:
1:2:3
3:7:1
2:1:2
你必须编程找出使这三种饲料用量最少的方案,要是不能用这三种饲料调配目标饲料,输出’NONE’。'用量最少’意味着三种饲料的用量(整数)的和必须最小。
对于上面的例子,你可以用8份饲料1,2份饲料2,和5份饲料3,来得到7份目标饲料: 8*(1:2:3) + 1*(3:7:1) + 5*(2:1:2) = (21:28:35) = 7*(3:4:5)
以上数字中,表示饲料比例的整数都是小于100(数量级)的非负整数,表示各种饲料的份数的整数都小于100。一种混合物的比例不会由其他混合物的比例直接相加得到。
#include <cstdio>
#include <cstring>
/**
*函数rule判别xyz与abc是否成比例关系,返回倍数。
*/
int rule(double x,double y,double z,int a,int b,int c)
{
if(a!=0&&b!=0&&c!=0)
{
if((x/a==y/b)&&(y/b==z/c))
return int(x/a);
else
return 0;
}
else if(a==0&&b!=0&&c!=0)
{
if((y/b==z/c)&&x==0)
return int(y/b);
else
return 0;
}
else if(a!=0&&b==0&&c!=0)
{
if((x/a==z/c)&&y==0)
return int(x/a);
else
return 0;
}
else if(a!=0&&b!=0&&c==0)
{
if((y/b==x/a)&&z==0)
return int(y/b);
else
return 0;
}
}
int main(){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
int a[3][3];
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
scanf("%d",&a[i][j]);
}
}
int minsum=999;
int mini,minj,mink,times;
int beishu=0;
for(int i=0;i<100;i++)
{
for(int j=0;j<100;j++)
{
for(int k=0;k<100;k++)
{
double temx=double(i*a[0][0]+j*a[1][0]+k*a[2][0]);
double temy=double(i*a[0][1]+j*a[1][1]+k*a[2][1]);
double temz=double(i*a[0][2]+j*a[1][2]+k*a[2][2]);
times=rule(temx,temy,temz,x,y,z);
if(times)//如果成倍数关系
{
int sum=i+j+k;
if(sum<minsum)//求最小的倍数
{
minsum=sum;
mini=i;minj=j;mink=k;
beishu=times;
}
}
}
}
}
if(minsum==999)
{
printf("NONE");
}
else
{
printf("%d %d %d %d",mini,minj,mink,beishu);
}
}
81 求小数位数个数
题目描述: 明明的问题可以归结为:给你一个浮点数,请你求出这个浮点数的小数位数。
思路:遍历数组,从小数点后面开始计数
#include<stdio.h>
int main()
{
int i,n,count;
char a[100];
while(scanf("%s",&a)!=EOF)
{
i=0;
count=0;
while(a[i]!='.')
{
i++;
}
i++;
while(a[i]!='\0')
{
count++;
i++;
}
printf("%d\n",count);
}
return 0;
}
82 进制转换
题目描述:输入一个十进制数,将其化成N进制数输出(2≤N≤16)。 输出结果时,大于等于10的数字用字母代替,A代表10,B代表11以此类推
思路:转换为N进制存入数组中,逆序输出
#include <stdio.h>
int main(){
int m,N,i=0;
char num[100];
while(scanf("%d %d",&m,&N)!=EOF){
if(m==0) printf("0");
else if(N==10) printf("%d",m);//为十进制的话直接输出
else{
while(m){//转换为N进制存入数组
if(m%N>=10)//大于10进制
num[i]='A'+(m%N)-10;
else num[i]='0'+(m%N); //小于十进制,转换为字符存入数组
m=m/N;
i++;
}
for(int j=i-1;j>=0;j--)
printf("%c",num[j]);
}
printf("\n");
i=0;
}
return 0;
}
83 表达式求值
题目描述:以字符串形式输入仅有整数和加减(正负)号构成的表达式,输出该表达式的值。
思路:将所有非空格的数存入数组B,
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int main() {
char a[100];
char b[100];
int j;
while(gets(a))
{
memset(b,0,sizeof(b));
b[0]='+'; //默认第一个数字为正数
j=1;
for(int i=0;i<strlen(a);i++){ //所有非空格加入b数组
if(a[i]!=' ') b[j++]=a[i];
}
int res=0,temp;
for(int i=0;i<strlen(b);i++)
{
temp=0;
if(b[i]=='+'||b[i]=='-')
{
j=i+1; //i在符号上,j在数字上
while(b[j]>='0'&&b[j]<='9'){ //数字的话,多位数相应计算
temp=temp*10+b[j++]-'0'; //注意j一定要自增,否则死循环
}
if(b[i]=='+'){
res+=temp;
}
else res-=temp;
}
i=j-1; //此时i从下一个数字开始
}
printf("%d\n",res);
}
return 0;
}
84 删除字符
题目描述:从键盘输入一个字符串和一个字符,将输入字符从字符串中删除,输出新的字符串。如果字符串中没有此字符,则原样输出字符串
思路:将字符串中不等于该字符的字符存入另一个数组中,输出该数组
#include<stdio.h>
#include<string.h>
int main()
{
char str[100];
char s[30];
char a;
gets(str);
scanf("%c",&a);
int k=0;
for(int i=0;str[i]!='\0';i++)
{
if(str[i]!=a)
{
s[k++]=str[i];
}
}
for(int j=0;j<k;j++)
{
printf("%c",s[j]);
}
printf("\n");
return 0;
}
85 手机短号
题目描述:大家都知道,手机号是一个11位长的数字串,同时,作为学生,还可以申请加入校园网,如果加入成功,你将另外拥有一个短号。假设所有的短号都是“6”+手机号的后5位,比如号码为13512345678的手机,对应的短号就是645678。
现在,如果给你一个11位长的手机号码,你能找出对应的短号吗
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void pus(char str[])
{
int j;
printf("6");
for(j=6;str[j]!='\0';j++)//从第7位开始输出直到遇到\0
{
printf("%c",str[j]);
}
printf("\n");
}
int main()
{
int n;
char str[12];
scanf("%d",&n);
getchar();
while(n--)
{
gets(str);
pus(str);
}
return 0;
}
86 字符串统计
题目描述:对于给定的一个字符串,统计其中小写字母出现的次数。
#include<stdio.h>
#include<string.h>
int countz(char str[])
{
int i,count=0;
for(i=0;str[i]!='\0';i++)
{
if(str[i]>='a'&&str[i]<='z')//统计小写字母出现的次数
{
++count;
}
}
return count;
}
int main()
{
int n;
char str[100];
int sum;
scanf("%d",&n);
getchar();
while(n--)
{
sum=0;
gets(str);
sum=countz(str);
printf("%d\n",sum);
}
return 0;
}
87 弟弟的作业
题目描述:你的弟弟刚做完了“100以内数的加减法”这部分的作业,请你帮他检查一下。每道题目(包括弟弟的答案)的格式为a+b=c或者a-b=c,其中a和b是作业中给出的,均为不超过100的非负整数;c是弟弟算出的答案,可能是不超过200的非负整数,也可能是单个字符"?",表示他不会算。
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
char str[100];
int count=0;
int op1,op2,res,answer;
char ch1,ch2;
while(scanf("%s",str)!=EOF)
{
//strchr函数返回该字符在字符串中第一次出现的位置
if(strchr(str,'?')==0)//如果没有出现?则进行计算,否则跳过该行
{
sscanf(str,"%d%c%d%c%d",&op1,&ch1,&op2,&ch2,&res);
if(ch1=='-')
{
answer=op1-op2;
}
if(ch1=='+')
{
answer=op1+op2;
}
if(res==answer)
{
++count;
}
}
}
printf("%d\n",count);
return 0;
}
88 字符串排序
题目描述:明明爸爸的问题可以归结为:输入一行字符串,全部由小写字母构成,对字符串按26个英文字母的先后顺序进行排序,然后输出。
思路:字符串排序和数字排序一样,本次采用插入排序,可以试试堆排序或者快速排序更快
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main(){
int len,i,j;
char str[101];
char key;
while(gets(str)){
len=strlen(str);
for(i=1;i<len;i++){
if(str[i]<str[i-1]){
key=str[i];
for(j=i-1;j>=0 && key < str[j];j--){
str[j+1]=str[j];
}
str[j+1]=key;
}
}
puts(str);
}
return 0;
}
89 回文问题
题目描述:输入一串字符,其长度小于200,判断该串字符是否构成回文。 所谓回文是指从左到右和从右到左读一串字符的值是一样的,如:ABCBA。
思路:双指针遍历,一个指向头,往后遍历,一个指向尾,向前遍历,若这两个元素不相等,则不是回文
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
char a[200];
int l,r,len,i;
int flag;
while(gets(a))
{
len=strlen(a);
flag=1;
for(l=0,r=len-1;l<len/2;l++,r--)
{
if(a[l]!=a[r])
{
flag=0;
printf("No\n");
break;
}
}
if(flag==1)
printf("Yes\n");
}
return 0;
}
90 字符串中找整数
题目描述:对于一个字符串,编程找出其中的所有整数。例如,字符串“a12bc34d05”,其中有整数12、34、5
思路:需要使用isdigit函数判断是否为数字,使用另一个数组来存储数字
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void count(char str[],int len)
{
int i,j,k;
int a[501]={0};
j=0;
for(i=0;i<len;i++)
{
//内置是isdigit判断字符是否为数字
if(isdigit(str[i]))
{
while(isdigit(str[i]))
{
k=str[i]-'0';
a[j]=k+a[j]*10;
i++;
}
j++;
}
}
printf("%d",j);
for(i=0;i<j;i++)
{
printf(" %d",a[i]);
}
printf("\n");
}
int main()
{
char str[100];
int len;
while(gets(str))
{
len=strlen(str);
count(str,len);
}
return 0;
}
91 乒乓球
题目描述:明明的问题可以归结为:给你一系列的比赛数据(WL形式),分别按照11分制和21分制的比赛规则进行统计,然后输出统计结果。
思路:遍历统计W和L的个数,若它们之间相差两分且有一个已经达到11分或者21分时输出,并且重新开始计数
#include <stdio.h>
#include <stdlib.h>
//
void regulation(char temp[],int len,int rule) {
int m=0,n=0,i;
for(i=0;i<len;i++) {
if(temp[i]=='W') {
m++;
} else if(temp[i]=='L'){
n++;
}
//当比分相差两分且已经达到11分或者21分时输出,并且重新开始计数
if((m>=rule||n>=rule)&&(m-n>=2||n-m>=2)) {
printf("%d:%d\n",m,n);
m=0;
n=0;
}
}
if(m!=0||n!=0)
printf("%d:%d\n",m,n);
}
int main(int argc, char *argv[]) {
char temp[300];
int i;
while(scanf("%c",&temp[0])!=EOF) {
i=1;
while(1) {
scanf("%c",&temp[i]);
if(temp[i]=='E') {
break;
}
++i;
}
regulation(temp,i+1,11);
printf("\n");
regulation(temp,i+1,21);
printf("\n");
}
return 0;
}
92 字符串统计
题目描述:明明最近在做一个有关字符串的统计工作。两个由小写字母组成的字符串s1和s2,明明需要统计出以下四种关系:
(1)在s1或s2中存在的字母(包括在s1和s2中都存在的字母);
(2)在s1中且在s2中的字母;
(3)在s1中但不在s2中的字母,在s2中但不在s1中的字母;
(4)不在s1中且也不在s2中的字母;
思路:将字符串转换为数字存储在数组中
#include <stdio.h>
#include <string.h>
//s1,s2存储输入的字符串,a[],b[]将字符串转换为数字并在此数组标记位置
int main()
{
char s1[30],s2[30],len1,len2,i,a[30],b[30],count=0;
while(gets(s1))
{
gets(s2);
len1=strlen(s1);
len2=strlen(s2);
//初始化
for(i=0;i<30;i++)
{
a[i]=0;
b[i]=0;
}
if(count!=0)
{
//控制输出的空行
printf("\n");
}
//将字符数组转换为对应数字
for(i=0;i<len1;i++)
{
a[s1[i]-96]=1;
}
for(i=0;i<len2;i++)
{
b[s2[i]-96]=1;
}
//转换成字符对应输出
printf("in s1 or s2:");
for(i=0;i<30;i++)
{
if(a[i]==1||b[i]==1)
{
printf("%c",i+96);
}
}
printf("\nin s1 and s2:");
for(i=0;i<30;i++) {
if(a[i]==1 && b[i]==1)
printf("%c",i+96);
}
printf("\nin s1 but not in s2 ,or in s2 but not in s1:");
for(i=0;i<30;i++) {
if((a[i]==1&&b[i] != 1) || (a[i] != 1 && b[i]==1))
printf("%c",i+96);
}
printf("\nnot in s1 and s2:");
for(i=1;i<27;i++) {
if(a[i]==0 && b[i]==0)
printf("%c",i+96);
}
printf("\n");
count++;
}
return 0;
}
93 隐藏口令
题目描述:有时候程序员有很奇怪的方法来隐藏他们的口令。
Billy"Hacker"Geits会选择一个字符串S(由L个小写字母组成,5<=L<=100,000),然后他把S顺时针绕成一个圈。
如字符串cbadfa,绕成一个圈后,我们认为字符串首尾相连。
每次取其中一个字母作为起始字母,并顺时针依次取字母而组成一个字符串。这样将得到一些字符串。
比如字符串cbadfa,按照以上规则取出的字符串有:
cbadfa badfac adfacb dfacba facbad acbadf
我们找到最小的那个字符串,可知为acbadf,也可知道它的第一个字符’a’在原字符串cbadfa中为第6个字符(位置从1开始),
将得到的结果6减1得到5,这就是我们需要的口令。
再比如字符串alabala,绕成一个圈后,每次取其中一个字母作为起始字母,并顺时针依次取字母而组成一个字符串。这样将得到一些字符串:
alabala labalaa abalaal balaala alaalab laalaba aalabal
我们找到最小的那个字符串,可知为aalabal,它的第一个字母’a’在原字符串中位置为7,7-1=6,则6为口令。
注:如果按照规则有两个字符串都是最小的,则取前面那一个。
#include<stdio.h>
#include<string.h>
#define max 100005
int main()
{
int n;
int i=0,j=0,k=0;
int index=0;//取的字符下标
char inital[max]="";//原始字符串
char str[max]="";//构造后的字符串
char minstr[max]="";//最小字符串
int minindex=0;//最小字符串在原字符串中的开始下标
//最小字符串初始化
minstr[0]='z'+10;
minstr[1]='\0';
//输入数据位数
scanf("%d",&n);
getchar();
char ch;
while (i < n) {
ch = getchar();
if (ch != '\n')
inital[i++] = ch;
}
inital[i] = '\0';
//暴力破解
for(i=0;i<n;i++)
{
k=0;//构造后的字符串下标
for(j=0;j<n;j++)
{
index=i+j;
if(index>=n)
{
index-=n;
}
str[k++]=inital[index];//构造后的字符串
}
str[k]='\0';
//求最小字符串
if(strcmp(str,minstr)==-1)
{
minindex=i;//最小的下标
strcpy(minstr,str);
}
}
printf("%d\n",minindex);
return 0;
}
94 求字符串的起始位置
题目描述:明明的问题可以归结为:输入两串字符串s和subs,求s中subs的起始位置。
#include <stdio.h>
#include <string.h>
int main() {
char s1[100],s2[100];
int len1,i,k,len2,start,count;
while(gets(s1) != NULL) {
gets(s2);
len1=strlen(s1);
len2=strlen(s2);
k=0,count=0;
for(i=0;i<len1;i++) {
if(s1[i]==s2[k]) {
count++; //统计与子串相等字母的个数
if(k==0) {
start=i+1; //记住与子串第一个字母相等的位置
}
k++;
} else { //遇到不相等的字符,从头子串初始位置开始统计
k=0;
start=0;
count=0;
}
if(count==len2) { //与子串全部匹配,输出起始位置
printf("%d\n",start);
break;
}
}
if(count != len2) //不与子串或者与部分子串匹配,输出0
printf("0\n");
}
return 0;
}
95 最长的单词
题目描述:明明的问题可以归结为:在一行英文单词中,找出其中最长的单词(若有多个最长,找出第一个出现的),并输出这个单词的长度
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//思路:用字符串数组str1[]存储输入的字符串,str2存储最大的字符串,count存储最大字符串的字符个数
int main(int argc, char *argv[]) {
char str1[1000],str2[1000];
int i,j,len,count,k,max;
while(gets(str1) != NULL) {
len=strlen(str1);
count=0,max=0;
for(i=0;i<len;i++) {//判断字符串字符个数
if(str1[i] !=' ') {
++count;
}
else if(str1[i]==' '){ //如果是空格,则要比较前面的字符串字符数量是否大于max
if(max<count) {
k=0;
for(j=i-count;j<i;j++) {//若大于,则将该字符串赋值到str2中
str2[k]=str1[j];
k++;
}
max=count;
}
count=0;//开始计数下一个空格后字符串的大小
}
}
if(max<count) {//别忘了还有最后一个字符串没有比较
k=0;
for(j=i-count;j<i;j++) {
str2[k]=str1[j];
k++;
}
max=count;
}
//输出
printf("%d ",max);
for(i=0;i<max;i++)
printf("%c",str2[i]);
printf("\n");
}
return 0;
}
96 奖学金
题目描述:明明所在学校的惯例是在每学期的期末考试之后发放奖学金。
发放的奖学金共有五种,获取的条件各不相同:
-
院士奖学金:每人8000元,期末平均成绩高于80分,并且在本学期内发表1篇或1篇以上论文的学生均可获得。
-
五四奖学金:每人4000元,期末平均成绩高于85分,并且班级评议成绩高于80分的学生均可获得。
-
成绩优秀奖:每人2000元,期末平均成绩高于90分的学生均可获得。
-
西部奖学金:每人1000元,期末平均成绩高于85分的西部省份学生均可获得。
-
班级贡献奖:每人850元,班级评议成绩高于80分的学生干部均可获得。
只要符合条件就可以得奖。 每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。
例如明明的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。
由于老师在学期末的时候很忙,所以,他把奖学金统计的事情交给明明做。老师把考试的相关数据给了明明,让他统计出以下数据:
1) 哪位同学获得的奖学金最多;
2) 获得最多奖学金的同学一共获得了多少奖学金;
3) 所有获得奖学金的同学一共获得了多少奖学金;
明明虽然很愿意帮老师这个忙,但是他发现,同学的数量很多,统计起来很麻烦,经常有统计出错的情况发生。于是明明就想请你帮一个忙,帮他写一个统计程序,统计出以上三项内容。
#include <stdio.h>
#include <string.h>
int main() {
int N,i,avgScore,claScore,paper,sum,max,temp,flag=0;
char name[50],t[50];
char leader,west;
while(scanf("%d",&N) != EOF) {
if(flag)
printf("\n");
sum=0,max=0;
for(i=0;i<N;i++) {
temp=0;
scanf("%s %d %d %c %c %d",name,&avgScore,&claScore,&leader,&west,&paper); //空格必须有,%c不能用%s,否则无法通过测试用例
if(avgScore>90) {
sum +=2000;
temp +=2000;
}
if(avgScore>85 && claScore>80) {
sum +=4000;
temp += 4000;
}
if(avgScore>80 && paper>=1) {
sum += 8000;
temp += 8000;
}
if(avgScore>85 && west=='Y') {
sum += 1000;
temp += 1000;
}
if(claScore>80 && leader=='Y') {
sum += 850;
temp += 850;
}
if(temp>max) {
strcpy(t,name); //字符串复制
max=temp;
}
}
printf("%s\n",t);
printf("%d\n",max);
printf("%d\n",sum);
flag=1;
}
return 0;
}
97 回文数2
题目描述:明明的问题可以归结为:给你一个整数(十进制),判断该整数的十进制数和它的二进制数是否全为回文数。
思路:用数组存储十进制转换为R进制的结果,再判断由该数组组成的元素是否为回文
#include<stdio.h>
int hui(int n,int r)
{
int a[100],i=0,j;
while(n)
{
a[i++]=n%r;
n/=r;
}
for(j=0;j<i;j++)
{
if(a[j]!=a[i-1-j])
return 0;
}
return 1;
}
int main()
{
int N,m;
while(scanf("%d",&N)!=EOF)
{
m=hui(N,10);
if(m==0)
printf("No\n");
else
{
m = hui(N,2);
if(m==1)
{
printf("Yes\n");
}
else
printf("No\n");
}
}
return 0;
}
98 加法器
题目描述:明明的问题可以归结为:给你一串正整数的连加表达式,完成这个表达式的计算。
注意不要忘了加上最后一位
#include<stdio.h>
#include<string.h>
int main()
{
char str[1000];
int len,i,flag,num,sum;
while(gets(str))
{
flag=1;//用来标记是否为数字的第一位
sum=0;
len=strlen(str);
for(i=0;i<len;i++)
{
if(str[i]!='+')
{
if(flag==1)
{
num=str[i]-'0';//如果是第一位,将字符转换为数字
flag=0;
}
else
{
num=num*10+(str[i]-'0');//数字位数大于1位
}
}
else
{
flag=1;//开始为下一个数字的第一位
sum+=num;//碰到+号,下一位是数字的第一位
}
}
printf("%d\n",sum+num);//记住还要加最后一位数
}
return 0;
}
99 构造序列
题目描述:序列是在数学世界中一种非常有趣的数字现象,它通过某一规则来产生数字,使数字变得有趣、变幻无穷。很多数学家对序列这种事物产生了浓厚的兴趣,花了很多时间对其进行研究,明明就是其中的一位。一天,他又在研究一种新的序列产生规则,该序列的规则如下:
1) 第1轮,写出两个1,即11;
2) 第2轮,在它们中间插入2,成为121;
3) 第3轮,在上面数中每两个相邻的和为3的数之间插入3,成为13231;
4) 以此类推下去,第n轮,在第n-1轮的数字的基础上,每两个相邻的和为n的数之间插入n。
明明根据这个规则开始构造序列。开始还觉得容易,但是越到后面,明明发现构造序列的计算量越来越大,计算难度也越来越高,计算速度也越来越慢。于是,明明就求助于你这位程序设计专家,能否帮他写一个程序,构造出序列的前9项,然后当明明需要知道序列中的哪一项的时,你就把那一项的数字告诉明明。
明明的问题可以归结为:根据题目描述中所描述的序列产生规则构造序列的前9项,然后告诉你一个正整数n,要求你输出序列的第n项。
思路: 我直接手打😎
#include<iostream>
#include<string>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n=0;//n为原始数的进制
char a[500] = {0};
while (cin >> n)
{
if (n == 1)cout << 11 << endl;
if (n == 2)cout << 121 << endl;
if (n == 3)cout << 13231 << endl;
if (n == 4)cout << 1432341 << endl;
if (n == 5)cout << 15435253451<< endl;
if (n == 6)cout << "1654352534561" << endl;
if (n == 7)cout << "1765473572753745671" << endl;
if (n == 8)cout <<"18765473857275837456781" << endl;
if (n == 9)cout <<"19876594738579297583749567891" << endl;
}
//system("pause");
return 0;
}
100 纯粹合数
题目描述:明明的问题可以归结为:根据一个正整数n,求出从100开始从小到大的第n个纯粹合数。
思路:要用到sprintf函数和sscanf函数
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int isComposite(int n){
int i;
for(i=2;i<=sqrt(n);i++){
if(n%i==0){
return 1;
}
}
return 0;
}
int isPure(int n){
char temp[10];
sprintf(temp,"%d",n);//把数字输出到数组中
int len = strlen(temp),i=0;
while(len--){
int num;
sscanf(temp,"%d",&num);//读取数组中的数字
if (num!=0&&isComposite(num)==0)
{
return 0;
}
temp[i++] ='0';//依次将最高位变为0
}
return 1;
}
int main(int argc, char *argv[]) {
int n,i,count;
while(scanf("%d",&n)!=EOF){
count=0;
i=100;
while(1){
if(isPure(i)){
++count;
}
if(count==n){
printf("%d\n",i);
break;
}
++i;
}
}
return 0;
}
101 找出质数
题目描述:明明爸爸的问题可以归结为:输入一串数字,找出其中最长的不超过4个字符的质数子串。若有多个答案,则找出其中数值最大的一个。
思路:用字符数组存储该串数字,使用暴力破解法,每次依次判断前四位是否构成质数,若构成则令MAX等于它,否则从下一位开始,判断前四位是否构成质数,一直循环到最后四位。
#include<iostream>
#include<cstring>
using namespace std;
#include<algorithm>
#define MAX 10000000
using namespace std;
int Zishu(int num)
{
if(num==0&&num==1) return 0;
for(int i=2;i<num;i++)
{
if(num%i==0)
return 0;
}
return 1;
}
//使用暴力破解法
//每次依次判断前四位是否构成质数,若构成则令max=它,若不构成则从下一位开始比较
int main()
{
char s[100];
int num,count,max;
while(cin>>s)
{
int sum,max=-1;
for(int i=0;i<strlen(s);i++)
{
sum=0;
count=0;
num=s[i]-'0';
while(count<4&&i<strlen(s))
{
sum=sum*10+num;
if(Zishu(sum)&&sum>max)//判断是否为 质数且是否大于当前统计的最大的四位数
max=sum;
count++;//每次统计四位
i++;//数组下标
num=s[i]-'0';
}
i=i-count;
}
cout<<max<<endl;
}
return 0;
}
102 翻译字符串
题目描述:明明的破解方法如下:一串以‘@’为结束标志的字符串,从左至右对其进行翻译,若字符串中当前字符是整数n(0≤n≤9),则表示将后一个字符重复n+1次,不论后一个字符是否为数字,且后一个字符无需再次翻译;若当前字符非数字,则表示自己,无需翻译,直接输出即可。最后,输出翻译完的字符串。
例如字符串为:2d352d@,因为第一个字符为数字2,则将后一个字符d输出3次,而d则不需再翻译,然后翻译3,3也是一个数字,则将后一个字符5输出4次,而5则不需再翻译,然后翻译2,2也是一个数字,将后一个字符d输出3次,而d则不需再翻译,最后一个字符为@,表示自己,直接输出即可,最后的输出为:ddd 555 5dd d@;(注:在翻译时,‘@’当作字符处理。) 这样翻译字符串的方法虽然简单,但是由于敌方的文件巨大,仅仅靠手工翻译是很难在短时间内完成的。于是明明就求助于你这位程序专家,按照明明提供的破译方法写一个程序,帮助明明快速把敌方文件翻译完成。
明明的问题可以归结为:按照文中提供的破译情报的方法,对字符串进行翻译,然后输出翻译后的字符串。
思路:循环读取字符串中字符,若为数字,则输出对应次数+1,然后下标加1,即跳过下一个,不是数字的话直接输出,依次重复进行
#include<stdio.h>
#include<string.h>
//写一个循环读入字符串,若为数字,则输出对应次数,然后i++,跳过下一个,若count=3需要打上一个空格
int main()
{
char str[10];//输入的字符串
int i,len,j,count;
while(gets(str))
{
count=0;//计数输出了多少字符,若为3则需要输出一个空格
for(i=0;i<strlen(str);i++)
{
if(str[i]>='0'&&str[i]<='9')//为数字
{
j=0;//表示数字大小,需要重复输出的次数,即str[i]+1次
while(j<=str[i]-'0')
{
if(count==3)//输出三次需要输出一个空格
{
count=1;//表示已经输出了一个
printf(" ");
printf("%c",str[i+1]);
}
else
{
printf("%c",str[i+1]);
++count;
}
//
++j;
}
++i;//跳过一位
}
else
{
//不是数字的话直接输出
if(count==3)
{
count=1;
printf(" %c",str[i]);
} else{
printf("%c",str[i]);
++count;
}
}
}
printf("\n");
}
return 0;
}
103 分割数字并排序
题目描述:输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数就是0)。
你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。
#include <stdio.h>
#include <string.h>
void sort(int number[], int len){//C++可以直接用内置的sort函数
int i, j;
int temp;
for (i = 0; i < len;i++)
for (j = 0; j < len-i-1; j++){
if (number[j]>number[j + 1]){
temp = number[j];
number[j] = number[j+1];
number[j + 1] = temp;
}
}
}
int main(){
int n;
while (scanf("%d", &n) != EOF){
while (n--){
char number[1000];
int store[1000];//cc 存储结果
int count = 0;//存储结果的下标
scanf("%s", number);//存储输入的字符串
int len = strlen(number);
int i;
int sum = 0;//记录当前的数字
int flag = 0;
for (i = 0; i < len; i++){
if (number[i] == '5'&&(flag==1)){
store[count++] = sum;//遇到5,将该数前面的数存入数组
sum = 0;
flag = 0;
continue;
}
if (number[i] == '5' && (flag == 0))//开头字母为5则跳过
continue;
if(number[i]!='5') {
sum = sum * 10 + number[i] - '0';
flag = 1;
}
if (i == len - 1&&number[i]!='5')//最后的那个数字要记得存储
store[count++] = sum;
}
sort(store, count);//对结果排序
for (i = 0; i < count; i++){
if (i == count - 1){
printf("%d\n", store[i]);
break;
}
else printf("%d ", store[i]);
}
}
}
return 0;
}
104 A == B
题目描述:给你两个非负实数A和B,如果A等于B,输出 “YES”, 否则输出"NO"
思路:需要将两个字符串A,B规范化,即删除开头字母是0的字符以及删除末尾字母为0的字符,然后再用strcmp函数比较两字符是否相等
#include<iostream>
#include<string>
#include<bits/stdc++.h>
using namespace std;
//判断是否存在小数点
int existpoint(char a[])
{
for (int i = 0; a[i] != '\0'; i++)
{
if (a[i] == '.')return 1;
}
return 0;
}
//做一个删除字符串首项的函数
void removef(char a[])//a为给定数组,n为初始有效元素个数
{
int n = strlen(a);
for (int i = 0; i < n - 1; i++)//将后面的数往前移
{
a[i] = a[i + 1];
}
a[n - 1] = '\0';
}
//做一个删除字符串最后一项的函数
void removel(char a[])
{
int n = strlen(a);
a[n - 1] = '\0';
}
void trans(char a[])
{
while (a[0] == '0')//删除开头为0的字符
{
removef(a);
}
int len = strlen(a);
if (existpoint(a)==1)//先判有无小数点,有的话删末位0
{
while (a[len - 1] == '0')//删除末尾为0的字符
{
removel(a); len--;
}
}
if (a[len - 1] == '.')//若小数点后面全是0,还需将小数点删除
{
removel(a); len--;
}
}
int main()
{
int n=0;
cin >> n; getchar();
char a[1010];
char b[1010];
while (cin.getline(a,1010,' '),cin.getline(b,1010),n--)
{
trans(a);
trans(b);
if (strcmp(a, b) == 0)
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
return 0;
}
105 母牛制造的回文
题目描述:你的工作就是去这些牛制造的奇观(最棒的回文)。在寻找回文时不用理睬那些标点符号、空格(但应该保留下来以便做为答案输出),只用考虑字母’A’-‘Z’和’a’-‘z’。要你寻找的最长的回文的文章是一个不超过20,000个字符的字符串。我们将保证最长的回文不会超过2,000个字符(在除去标点符号、空格之前)。
思路:结构体存储字符和
#include <cstdio>
#include <cstring>
typedef struct data_site{
char data;
int site;//该字符所在下标
};
int ishui(data_site a[],int start,int end)//又一种判断回文的方法
{
int flag=1;
for(int i=0;i<end-start+1;i++)//end-start+1表示在当前区间的字符数量
{
if(a[start+i].data!=a[end-i].data)
{
flag=0;
break;
}
}
if(flag==1)
{
return 1;
}
else
{
return 0;
}
}
int main(){
char a[20000];
char t;
int r=0;
while(t=getchar())
{
if(t == EOF)
break;
a[r++]=t;//数组a存储输入的字符
}
data_site x[20000];
int len=0;
for(int i=0;i<strlen(a);i++)
{
if(a[i]>='a'&&a[i]<='z')//结构体x存储字符串中的字符和其所在下标
{
x[len].data=a[i];
x[len].site=i;
len++;
}
else if(a[i]>='A'&&a[i]<='Z')//将大写字母转小写并存入结构体X中
{
x[len].data=a[i]-'A'+'a'; //x[len].data=a[i]+32是否可行?
x[len].site=i;
len++;
}
}
int maxlen=0,maxstart=0,maxend=0;//存储最大的回文的长度,开头下标和结尾下标
for(int i=0;i<len;i++)
{
int templen=1;//存储当前回文的长度
for(int j=i+1;j<len;j++)
{
if(ishui(x,i,j))
{
templen=j-i+1;
}
}
if(templen>maxlen)
{
maxlen=templen;
maxstart=x[i].site;
maxend=x[i+templen-1].site;
}
}
printf("%d\n",maxlen);
for(int i=maxstart;i<=maxend;i++)
{
printf("%c",a[i]);
}
}
106 大整数相加
Description of the title:I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.
思路:注意要将字符转换为数字以及处理进位【从个位开始相加】,还有输出的格式
#include <stdio.h>
#include <string.h>
int main(){
int T;
scanf("%d", &T);
int j,k;
for (j = 1; j <= T; j++){
char number1[1000];
char number2[1000];
int sum[1000] = {0};//置0,存储相加后的结果
//memset(sum, 0, sizeof(int));//int 类型怎么置0
scanf("%s%s", number1, number2);
int len1 = strlen(number1);
int len2 = strlen(number2);
int i;
for (i = 0; i < len1 || i < len2; i++){
if (i < len1)
sum[i] += number1[len1 - i - 1] - '0';//字符转换为数字
if (i < len2)
sum[i] += number2[len2 - i - 1] - '0';
if (sum[i] >= 10)//处理进位
{
sum[i + 1] = sum[i] / 10;
sum[i] = sum[i] % 10;
}
}
printf("Case %d:\n", j);//格式输出
for (k = 0; k<len1; k++)
printf("%c", number1[k]);
printf(" ");
printf("+");
printf(" ");
for (k = 0; k<len2; k++)
printf("%c", number2[k]);
printf(" ");
printf("=");
printf(" ");
if (len1 < len2)//判断谁最长
len1 = len2;
if (sum[i]>0)//如果最高位不等于0,则输出
printf("%d", sum[i]);//最高位产生进位
for (i = len1 - 1; i >= 0; i--)
printf("%d", sum[i]);
printf("\n\n");
}
return 0;
}
//1.字符串处理大数加运算
//2.字符转换为数字(不要犯错误)
107 16进制加法
题目描述:T行,每行一个16进制数,为求出的两数之和。
思路:先将16进制化为10进制,然后再转换为十六进制存入数组输出
#include <stdio.h>
#include <math.h>
int main(){
char number[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
int T;
while(scanf("%d",&T)!=EOF){
while(T--){
char a[100],b[100];
scanf("%s%s",a,b);//以空格作为结束标志
char s1[100];
int i=0;
int j=0;
int sum1=0;
int sum2=0;
int count1=0;//统计两个字符串的长度
int count2=0;
while(a[i]!='\0')
{count1++;
i++;
}
i=0;
while(b[i]!='\0')
{
count2++;
i++;
}
i=0;
while(a[i]!='\0'){//将16进制化为10进制
for(j=0;j<16;j++)
{
if(a[i]==number[j])
sum1+=j*pow(16,count1-1-i);
}
i++;
j=0;
}
i=0;
while(b[i]!='\0'){
for(j=0;j<16;j++)
{
if(b[i]==number[j])
sum2+=j*pow(16,count2-1-i);
}
i++;
j=0;
}
int sum=sum1+sum2;
i=0;
while(sum){
s1[i++]=number[sum%16];//将十进制化为16进制并存入数组S1中
sum=sum/16;
}
for(j=i-1;j>=0;j--)
printf("%c",s1[j]);
printf("\n");
}
}
return 0;
}
108 纯粹素数
题目描述:明明的问题可以归结为:一个素数,去掉最高位,剩下的数仍为素数,再去掉剩下的数的最高位,余下的数还是素数,这样下去一直到最后剩下的个位数也还是素数,我们把这样的数称为纯粹素数。
跟据一个正整数n,求出从1,000开始从小到大的第n个纯粹素数。
思路:和第100题的纯粹合数解法相同
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int isPrime(int n){
int i;
if(n==1){
return 0;
}else if(n==2){
return 1;
}else{
for(i=2;i<=sqrt(n);i++){
if(n%i==0){
return 0;
}
}
return 1;
}
}
int isPure(int n){
char temp[10];
sprintf(temp,"%d",n);
int len = strlen(temp),i=0;
while(len--){
int num;
sscanf(temp,"%d",&num);
if (num!=0&&isPrime(num)==0){
return 0;
}
temp[i++] ='0';
}
return 1;
}
int main(int argc, char *argv[]) {
int n,i,count;
while(scanf("%d",&n)!=EOF){
count=0;
i=1000;
while(1){
if(isPure(i)){
++count;
}
if(count==n){
printf("%d\n",i);
break;
}
++i;
}
}
return 0;
}
109 大实数加法
题目描述:给你两个正的实数A和B,你的任务是计算出A+B的值。
思路:即高精度加法,先处理小数,再处理整数
#include <iostream>
#include<iomanip>
#include <cmath>
#include<bits/stdc++.h>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int k;
cin>>k;
int m=0;
while(m<k){
//输入第一个数的整数部分。
char a[400];
char b[400];
cin>>a;
cin>>b;
//计算数字的长度,以及小数点的位置
int count1=0;
int dotp1=0;
for(int i=0;a[i]!='\0';i++)
{
if(a[i]=='.')
dotp1=i;
count1++;
}
int count2=0;
int dotp2=0;
for(int i=0;b[i]!='\0';i++)
{
if(b[i]=='.')
dotp2=i;
count2++;
}
//进位标志
int up=0;
//处理小数部分
//小数部分长度l1,l2
int l1=count1-1-dotp1;
int l2=count2-1-dotp2;
int min2=l1<l2?l1:l2;
int r1=0;
int d[400];
//使用指针指向小数的最后一位,使操作统一
int index1=count1-1;
int index2=count2-1;
//将超出的部分先存起来
while(l1<l2&&r1<l2-l1){
//此处必须用变量接受,不然会出错
int x=b[index2--]-'0';
d[r1++]=x;
}
while(l1>l2&&r1<l1-l2){
int x=a[index1--]-'0';
d[r1++]=x;
}
for(int i=0;i<min2;i++)
{
int x=a[index1--]-'0';
int y=b[index2--]-'0';
d[r1++]=(x+y+up)%10;
up=(x+y+up)/10;
}
//处理整数部分
if(dotp1==0)
dotp1=1;
if(dotp2==0)
dotp2=1;
int min1=dotp1<dotp2?dotp1:dotp2;
int c[400];
int r=0;
for(int i=0;i<min1;i++)
{
int x=a[dotp1-i-1]-'0';
int y=b[dotp2-i-1]-'0';
c[r++]=(x+y+up)%10;
up=(x+y+up)/10;
}
while(dotp1>dotp2&&r<dotp1){
int x=a[dotp1-r-1]-'0';
c[r++]=(x+up)%10;
up=(x+up)/10;
}
while(dotp1<dotp2&&r<dotp2){
int x=b[dotp2-r-1]-'0';
c[r++]=(x+up)%10;
up=(x+up)/10;
}
if(up!=0)
c[r++]=up;
int j=0;
while(d[j]==0){
j++;
}
//cout<<j<<endl;
for(int i=r-1;i>=0;i--)
cout<<c[i];
//必须小于0,由于d[]中可能都是0
if(j-r1<0)
cout<<'.';
for(int i=r1-1;i>=j;i--)
{
cout<<d[i];
}
cout<<"\n";
m++;
}
return 0;
}