// 用于化简分子和分母 // 参数: // numerator - 分子 // numerator - 分母 voidreduce(int* numerator,int* denominator){ // 声明n和d只是因为*?打出来太麻烦了,可以选择直接用指针 int n =*numerator; int d =*denominator; int min = n < d ? n : d; for(int i = min; i !=1&&abs(n)>1;--i){ hear: if(n % i ==0&& d % i ==0){ n /= i; d /= i; goto hear; } } *numerator = n; *denominator = d; }
// 整数求base的power次幂 // 参数: // base - 底数 // power - 幂 intintPow(int base,int power){ int result =1; for(int i =0; i < power;++i){ result *= base; } return result; }
// 裁剪掉小数后面多余的0 voidpreProcess(char value[]){ int zeroIndex =-1; bool start = false; bool pre = false; for(int i =0; value[i]!='\0';++i){ if(start){ if(value[i]=='0'){ if(!pre){ zeroIndex = i; pre = true; } }else pre = false; }elseif(value[i]=='.'){ start = true; } } if(pre) value[zeroIndex]='\0'; }
intmain(){ // a0,a1为第一个数的分子和分母 // b0,b1为第二个数的分子和分母 // m为通分后的分母 int a0, a1, b0, b1, m; char op;// 操作符 int k =0;// 换行标识符,防止第一次计算也打印换行符 while(~scanf("%d/%d%c%d/%d",&a0,&a1,&op,&b0,&b1)){ if(k ==0) k =1; elseprintf("\n"); if(a1 == b1){// 如果两个数分母相同则不通分 m = a1; }else{// 如果分母不同则进行通分 m = a1 * b1; a0 *= b1; b0 *= a1; } int z = op =='+'? a0 + b0 : a0 - b0;// 加减操作 if(z ==0)printf("0"); elseif(z % m ==0)printf("%d", z / m); else{ reduce(&z,&m);// 化简 if(m * z <0)printf("-"); printf("%d/%d",abs(z),abs(m)); } } return0; }
置点不动产——认真学习,努力工作买买房子吧
这个题也很简单,需要注意的就是到底先判断年份还是先计算涨幅,直接上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
intmain(){ int n, k, i; scanf("%d %d",&n,&k); longlong sum = n; double money =200; double bl =(100+ k)/100.0; for(i =1; i !=21&& sum < money;++i){ sum += n; money *= bl; } if(i ==21)printf("Impossible"); elseprintf("%d", i); return0; }
综艺节目打分计算问题
这个题有两个思路:
先输入所有值,然后排序,最后计算除去首位和末尾的总值并求平均数
计算所有数的总和,然后减去最大值和最小值,最后求平均值
很明显第二个思路更加简单,这里也直接给出代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
intmain(){ unsignedlonglong sum =0; int min =101, max =-1; int temp; int size =-2; while(~scanf("%d",&temp)){ sum += temp; if(temp < min) min = temp; if(temp > max) max = temp; ++size; } sum -= min; sum -= max; printf("%lld", sum / size); return0; }
intmain(){ int n; scanf("%d",&n); for(int line =1; line <= n;++line){ int spaceLength = n - line; for(int space =0; space < spaceLength;++space)printf(" "); for(int i =1; i != line;++i)printf("%d", i); for(int i = line; i !=0;--i)printf("%d", i); printf("\n"); } return0; }
分段函数求值
非常简单的题目,不解释:
1 2 3 4 5 6 7 8 9 10 11 12 13
intmain(){ double x, result; scanf("%lf",&x); if(x <0){ result = x * x; }elseif(x <10){ result =2* x -1; }else{ result =3* x -11; } printf("%.2f", result); return0; }
// 获取上一个小朋友的下标 // 参数: // index - 当前下标 // n - 数组长度 intgetPre(int index,int n){ if(index -1==-1)return n -1; elsereturn index -1; }
// 获取下一个小朋友的下标 // 参数: // index - 当前下标 // n - 数组长度 intgetNext(int index,int n){ if(index +1== n)return0; elsereturn index +1; }
接下来我们需要处理分糖的操作,这里我们同样封装成一个函数,这样后面只需要无脑调用就可以了:
1 2 3 4 5 6 7 8 9 10
// 参数: // nums[] - 存储糖果数量的数组 // index - 要进行分糖的下朋友的下标 // n - 数组长度(小朋友的数量) voidtask(int nums[],int index,int n){ int k = nums[index]/3; nums[index]= k;// 更新当前小朋友糖的数量 nums[getPre(index, n)]+= k;// 增加左侧小朋友糖的数量 nums[getNext(index, n)]+= k;// 增加右侧小朋友糖的数量 }
输入、输出和无脑调用环节:
1 2 3 4 5 6 7 8 9 10 11
intmain(){ int n; scanf("%d",&n); int nums[n]; for(int i =0; i < n;++i)scanf("%d",&nums[i]); for(int i =0; i < n;++i){ task(nums, i, n); } for(int i =0; i < n;++i)printf(" %d", nums[i]); return0; }
真睡还是装睡
非常简单,不做解释:
1 2 3 4 5 6 7
intmain(){ int a, b; scanf("%d %d",&a,&b); if(a <15|| a >20|| b <50|| b >70)printf("F"); elseprintf("T"); return0; }
// 将数组形式的数转换为整型 lu arrayToInt(constint nums[],int n){ lu result =0; for(int i = n -1, s =1; i !=-1;--i, s *=10){ result += nums[i]* s; } return result; }
// 使当前回文数指定位数+1 // 参数: // nums[] - 当前回文数 // length - 回文数长度 // left - 左侧自加位点下标 // right - 右侧自加位点下标 // 返回值: // 是否生成成功,如果生成的新的回文数的位数大于length就会生成失败 // 注: // left 可以和 right 相等,两个值相等时不会重复自加 // 不论是否生成成功,都会修改 nums 的值 bool plus(int nums[],int length,int left,int right){ if(++nums[left]==10){ if(left ==0)return false; nums[left]= nums[right]=0; returnplus(nums, length, left -1, right +1); }else{ nums[right]= nums[left]; } return true; }
// 计算一个数的长度 intgetLength(int n){ int result =0; while(n !=0){ ++result; n /=10; } return result; }
// 生成一个最小的回文数 // 参数: // minNum - 最小值(不包含) lu createMinPalindrome(int minNum){ staticint cache[12];// 存储回文数 lu value =0;// 存储当前回文数的int值 int minLength =getLength(minNum);// 获取最小值的长度,以获取回文数的最小长度 // 如果最小数只有一位直接返回结果 if(minLength <=1)return minNum ==9?11: minNum +1; for(int length = minLength;;++length){ // 初始化cache memset(cache,0,sizeof(int)* length); cache[0]= cache[length -1]=1;// 首尾位置的数替换成1 int k = length /2;// 计算中点下标,奇偶情况分别处理 int left =(length %2==0? k -1: k); // 循环自增,直到比minNum大 // do-while的条件是为了在所有位都为9后进入下一次外部循环 // 这道题很明显只有minNum各个位上均为9时会进入第二次外部循环 // 因为概率出现较低,提前判断会让平均运行时间增大,就不提前判断了 do{ value =arrayToInt(cache, length); if(value > minNum)return value; }while(plus(cache, length, left, k)); } }