第三次上机总结
问题
- 已学内容的熟练度有待加强
- 对于
for
循环不太熟练
switch
使用方法(见下) break
的位置不对.有异常的退出循环的情况.在循环中要注意switch
的使用
int op;//如果是char就直接写case'A': case 'b': 等
switch(op){
case 1:
break;
case 2:
break;
case '1':
//相当于case 49 因为49=='1'
break;
default:
break;
}
AC代码
A 倒三角
- 杜晨鸿没工资辣
- 找规律 2层循环解决
- 问题:想复杂了 不会写循环 或者换行的位置不对
#include <stdio.h>
int main(){
int n,i,j;
scanf("%d",&n);
for(i = 0;i < n;i++){
for(j = 0;j < 2 * n - 1 - i;j++){
if(j<i){
putchar(' ');
}else{
putchar('$');
}
}
putchar('
');
}
return 0;
}
B 荷荷学妹赚基金
if-else
判断 注意数据范围.
- 后面有浮点数操作 所以建议直接读浮点数 注意
scanf
在此处的使用
- 可以不开数组
#include <stdio.h>
int main(){
double cur;
int n;
scanf("%d",&n);
while(n--){
scanf("%lf",&cur);
if(cur <= 800.){
printf("%.2f
",cur);
}
else if(cur <= 1500.){
printf("%.2f
",cur - (cur - 800) * 0.2);
}
else{
printf("%.2f
",cur - (cur - 1500) * 0.25 - 700 * 0.2);
}
}
return 0;
}
C 一天不用switch我浑身难受
- 题目背景似乎是造随机数
- 只要细致就能拿分
if-else
转switch
#include<stdio.h>
unsigned seed;
long long a, b;
long long ans = 0;
int n, i;
int op;
int scheme[35];
int main() {
scanf("%d%u", &n, &seed);
for (i = 0; i <= 31; ++i) scanf("%d", &scheme[i]);
while(n--)
{
seed ^= seed << 13;
seed ^= seed >> 17;
seed ^= seed << 5;
op = scheme[seed & 31] & 31;
a = n ^ 1145141919810ll;
b = n ^ 1919810114514ll;
switch(op)
{
case 0: ans += a + b;break;
case 1: ans += a - b;break;
case 2: ans += a * b;break;
case 3: ans += a / b;break;
case 4: ans += a % b;break;
case 5: ans += a & b;break;
case 6: ans += a | b;break;
case 7: ans += a ^ b;break;
case 8: ans -= a ^ b;break;
case 9: ans -= a | b;break;
case 10: ans -= a & b;break;
case 11: ans -= a % b;break;
case 12: ans -= a / b;break;
case 13: ans -= a * b;break;
case 14: ans -= a - b;break;
case 15: ans -= a + b;break;
case 16: ans &= a * b;break;
case 17: ans &= a / b;break;
case 18: ans &= a + b;break;
case 19: ans &= a - b;break;
case 20: ans &= a | b;break;
case 21: ans &= a ^ b;break;
case 22: ans &= a % b;break;
case 23: ans &= a & b;break;
case 24: ans ^= a / b;break;
case 25: ans ^= a * b;break;
case 26: ans ^= a - b;break;
case 27: ans ^= a + b;break;
case 28: ans ^= a ^ b;break;
case 29: ans ^= a | b;break;
case 30: ans ^= a & b;break;
case 31: ans ^= a % b;break;
}
}
printf("%lld", ans);
return 0;
}
D 年 度 好 题
- 分数的计算(数学问题)
- 一行代码解决最大公约数求法
int gcd(int m,int n){
return m%n?gcd(n,m%n):n;
}
#include <stdio.h>
int gcd(int m,int n){
return m % n?gcd(n,m % n):n;
}
int main(){
int a,b,c,d,p,q,g;
scanf("%d/%d %d/%d",&a,&b,&c,&d);
q = b * d;
p = a * d + b * c;
g = gcd(p,q);
printf("%d/%d
",p / g,q / g);
return 0;
}
E 银行
- 浮点数计算问题,前面的误差会被指数函数放大
- 题目作者的意思是 比较两个利率然后算指数
#include <stdio.h>
#include <math.h>
int eq(double a,double b){//这个函数用于判断浮点数相等
return fabs(a - b) < 1e-8;
}
int main(){
double s,m,n,s1,s2;int t;
scanf("%lf%lf%lf%d",&s,&m,&n,&t);
double p1,p2;
p1=pow((1.00 + m / 100.0),t);
p2=pow(pow(1.00 + n / 100.00,4.0),t);
s1 = s * p1;s2 = s * p2;
//printf("%.2f
%.2f
",s1,s2);
if(eq(p1,p2)){
printf("%.2f
%.2f
",s1,s1);
puts("Whatever");
}
else if(p1 > p2){
printf("%.2f
%.2f
",s1,s2);
puts("51Mole!!");
}
else{
printf("%.2f
%.2f
",s1,s2);
puts("51Seer!!");
}
return 0;
}
F 五荷一点都不喜欢重复
- 全排列问题 循环当然可以做 就是麻烦
- 官方题解大概长这样
#include<stdio.h>
int main()
{
int m,n,single,ten,hund,thou,tk;
scanf("%d%d",&m,&n);
if(n==3)
{
for(hund=1;hund<=m;hund++)
for(ten=1;ten<=m;ten++)
for(single=1;single<=m;single++)
if(hund!=ten&&ten!=single&&hund!=single)
printf("%d%d%d
",hund,ten,single);
}
else if(n==4)
{
for(thou=1;thou<=m;thou++)
for(hund=1;hund<=m;hund++)
for(ten=1;ten<=m;ten++)
for(single=1;single<=m;single++)
if(hund!=ten&&ten!=single&&hund!=single&&thou!=hund&&thou!=ten&&thou!=single)
printf("%d%d%d%d
",thou,hund,ten,single);
}
else if(n==5)
{
for(tk=1;tk<=m;tk++)
for(thou=1;thou<=m;thou++)
for(hund=1;hund<=m;hund++)
for(ten=1;ten<=m;ten++)
for(single=1;single<=m;single++)
if(hund!=ten&&ten!=single&&hund!=single&&thou!=hund&&thou!=ten&&thou!=single&&tk!=thou&&tk!=hund&&tk!=ten&&tk!=single)
printf("%d%d%d%d%d
",tk,thou,hund,ten,single);
}
return 0;
}
#include <stdio.h>
int vis[12] = {0},res[12] = {0},m,n;
void dfs(int k){
int i;
if(k == n){
for(i = 0;i < n;i++){
putchar(res[i]+'0');
}
putchar('
');
return;
}
else{
for(i = 1;i <= m;i++){
if(!vis[i]){
vis[i] = 1;
res[k] = i;
dfs(k + 1);
vis[i] = 0;
}
}
}
}
int main(){
scanf("%d%d",&m,&n);
dfs(0);
return 0;
}
G 缺项一元三次方程
- 数学问题,而且公式给了 需要掌握
math.h
的函数用法
- 在C89中,使用
double pow(double base,double exponent)
计算开立方。但是,它要求base
不能是负数。对于负数的base
- 处理方法当然是 化 正
- 助教说不推荐下面用'qsort'的写法 三个数排序还是很好写的:)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int cmp(const void *p,const void *q){
double a = *((double *)p),b = *((double *)q);
return a == b?0:(a > b?1:-1);
}
int main(){
double p,q,x[4] = {0};
scanf("%lf%lf",&p,&q);
double q2 = q * q,p3 = p * p * p;
double PI = acos(-1.0);
if(q2 > p3){
double tmp = q - sqrt(q2 - p3);
double tmp2 = q + sqrt(q2 - p3);
printf("%.10f",(tmp2 > 0?pow(tmp2,1 / 3.0):(-1) * pow(-tmp2,1 / 3.0)) + (tmp > 0?pow(tmp,1 / 3.0):(-1) * pow(-tmp,1 / 3.0)));
}
else{
x[0] = 2 * sqrt(p) * cos(acos(q / sqrt(p3)) / 3.);
x[1] = 2 * sqrt(p) * cos(acos(q / sqrt(p3)) / 3. + 2 * PI / 3.);
x[2] = 2 * sqrt(p) * cos(acos(q / sqrt(p3)) / 3. + 4 * PI / 3.);
qsort(x,3,sizeof(double),cmp);
printf("%.10f %.10f %.10f",x[0],x[1],x[2]);
}
return 0;
}
H 朵朵的日期计算
- 日期计算(这是曹助教感觉很头痛的事情)建议存模板
- Zeller公式 闰年
- 打包成函数真舒服
#include <stdio.h>
#include <math.h>
int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int zeller(int y,int m,int d){
int c = y / 100;y = y % 100;
int r= (y + (y / 4) + (c / 4) - 2 * c + (13 * (m + 1) / 5) + d - 1) % 7;
return r < 0?r + 7:r;
}
int leapyear(int y){
return((y % 400 == 0) || ((y % 100 != 0) && (y % 4 == 0)));
}
int dayofyear(int y,int m,int d){
days[2] = leapyear(y)?29:28;
int s = 0,i;
for(i = 1;i < m;i++){
s += days[i];
}
s += d;
return s;
}
int main(int argc,char **argv){
int y1,y,m,d;
scanf("%d%d%d%d",&y1,&y,&m,&d);
int w51 = zeller(y1,5,1);
int t = w51?15 - w51:8;
int dt1 = dayofyear(y1,m,d),dt2 = dayofyear(y1,5,t);
printf("%d
",t);
printf("%d
",abs(dt1-dt2));
return 0;
}