全文目录
🍕3.1小节——入门模拟->简单模拟
问题 A: 剩下的树
问题 B: A+B
问题 C: 特殊乘法
问题 D: 比较奇偶数个数
问题 E: Shortest Distance (20)
问题 F: A+B和C (15)
问题 G: 数字分类 (20)
问题 H: 部分A+B (15)
问题 I: 锤子剪刀布 (20)
B1001 害死人不偿命的(3n+1)猜想 (15 分)
1011 A+B 和 C (15 分)
1046 划拳 (15 分)
1008 数组元素循环右移问题 (20 分)
B1012 数字分类 (20 分)
B1018 锤子剪刀布 (20 分)
A1042 Shuffling Machine (20 分)
A1046 Shortest Distance (20 分)
A1065 A+B and C (64bit) (20 分)
B1010 一元多项式求导 (25 分)
1002 A+B for Polynomials (25 分)
1009 Product of Polynomials (25 分)
🐱🚀3.2小节——入门模拟->查找元素
问题 A: 统计同成绩学生人数
问题 B: 找x
问题 C: 查找学生信息
问题 D: 查找
问题 E: 学生查询
1041 考试座位号 (15 分)
1004 成绩排名 (20 分)
1028 人口普查 (20 分)
1032 挖掘机技术哪家强 (20 分)
1006 Sign In and Sign Out (25 分)
1011 World Cup Betting (20 分)
1036 Boys vs Girls (25 分)
🐱🐉3.3小节——入门模拟->图形输出
问题 A: 输出梯形
问题 B: Hello World for U
问题 C: 等腰梯形
问题 D: 沙漏图形
1036 跟奥巴马一起编程 (15 分)
1027 打印沙漏 (20 分)
1031 Hello World for U (20 分)
🐱👤3.4小节——入门模拟->日期处理
问题 A: 日期差值
问题 B: Day of Week
问题 C: 打印日期
问题 D: 日期类
问题 E: 日期累加
🐱👤3.5小节——入门模拟->进制转换
问题 A: 又一版 A+B
问题 B: 数制转换
问题 C: 进制转换
问题 D: 八进制
1022 D进制的A+B (20 分)
1037 在霍格沃茨找零钱 (20 分)
1019 General Palindromic Number (20 分)
1027 Colors in Mars (20 分)
1058 A+B in Hogwarts (20 分)
🐱👤3.6小节——入门模拟->字符串处理
问题 A: 字符串连接
问题 B: 首字母大写
问题 C: 字符串的查找删除
问题 D: 单词替换
问题 E: 字符串去特定字符
问题 F: 数组逆置
问题 G: 比较字符串
问题 H: 编排字符串
问题 I: 【字符串】回文串
1006 换个格式输出整数 (15 分)
1021 个位数统计 (15 分)
1031 查验身份证 (15 分)
1002 写出这个数 (20 分)
1009 说反话 (20 分)
1014 福尔摩斯的约会 (20 分)
1024 科学计数法 (20 分)
1048 数字加密 (20 分)
1001 A+B Format (20 分)
1005 Spell It Right (20 分)
1035 Password (20 分)
1077 Kuchiguse (20 分)
1082 Read Number in Chinese (25 分)
🍕3.1小节——入门模拟->简单模拟
地址合集:3.1小节——入门模拟->简单模拟
问题 A: 剩下的树
解题思路
读入L和M的值,只要L和M不全为0就进行循环计算,然后模拟就是
先把所有的端点都标记为有树**(利用memset直接标记,大家可以想想为啥为这里可以设置为1而int不可以)**
读入区间后把所有的区间内元素设置为没有树并统计少了几棵树。
#include<cstdio> #include<cstring> int main(){ int L, M; while(scanf("%d %d",&L,&M) && (L !=0 || M != 0)){ bool temp[L+1]; memset(temp,1,sizeof(temp)); int ans = L + 1; while(M--){ int a, b; scanf("%d %d", &a, &b); while(a <= b){ if(temp[a]) ans--,temp[a] = 0; a++; } } printf("%d\n",ans); } return 0; }
问题 B: A+B
解题思路
整个过程最重要的就是将字符串转化为整数。
1.读入两个字符串
2.将两个字符串转化为整数
2.1 判断符号 如果有符号先跳过
2.2 依次读入数字并跳过,
2.3 根据第一位符号来反转(这题没出int的负数比正数多一个的问题,不然更恶心)
3.返回结果
#include<cstdio> int string_to_num(char *s){ int i = 0, ans = 0; if(s[i] == '-') i++; for(;s[i] != '\0';i++){ if(s[i] == ',') continue; ans *= 10; ans += s[i] - '0'; } if(s[0] == '-') ans = -ans; return ans; } int main(){ char a[14],b[14]; while(scanf("%s %s", a, b) != EOF){ printf("%d\n",string_to_num(a) + string_to_num(b)); } return 0; }
问题 C: 特殊乘法
解题思路
整个过程最重要的就是将取出每一位的数据,这里经常采用的就是不断除以10取余数的方式。有点像转换成二进制的每一位的方式。除留余数法。
#include<cstdio> int matix(int a, int b){ int ans = 0; while(a){ int tempa = a % 10; a /= 10; int temp = b; while(b){ ans += tempa * (b % 10); b /= 10; } b = temp; } return ans; } int main(){ int a, b; while(scanf("%d %d", &a, &b) != EOF){ printf("%d\n",matix(a, b)); } return 0; }
问题 D: 比较奇偶数个数
解题思路
在输入过程中不断统计奇数的个数
如果最终的奇数个数超过了总数的一半 就输出YES
否则输出NO
#include<cstdio> int main(){ int n; while(scanf("%d",&n) != EOF){ int tempn = n,ans = 0; while(n--){ int temp; scanf("%d", &temp); if(temp & 1) ans++; //统计奇数个数 } if(ans > tempn /2) //奇数比较多 printf("YES\n"); else printf("NO\n"); } return 0; }
问题 E: Shortest Distance (20)
解题思路
真的好花里胡哨啊。。。。就是需要计算走那边更近,需要借助前缀和,直接看吧。。思想不复杂。
#include<cstdio> int main(){ int n; while(scanf("%d",&n) != EOF){ int temp[n+1]; temp[0] = 0; for(int i = 0;i < n;i++){ int tempa; scanf("%d",&tempa); temp[i+1] = temp[i] + tempa;//计算前缀和 } int m; scanf("%d",&m); while(m--){ int a, b; scanf("%d %d",&a,&b); int ans; if(a > b) ans = temp[a - 1] - temp[b - 1]; else ans = temp[b - 1] - temp[a - 1]; if(2 * ans > temp[n]) ans = temp[n] - ans; printf("%d\n",ans); } } return 0; }
问题 F: A+B和C (15)
解题思路
注意数据范围所以直接开到long long的数据了,另外注意序号是从1开始的,而变量一般是从0开始循环!
#include<cstdio> int main(){ int n; while(scanf("%d",&n) != EOF){ for(int i = 0;i < n; ++i){ long long a, b, c; scanf("%lld %lld %lld", &a, &b, &c); if(a + b > c) printf("Case #%d: true\n",i+1); else printf("Case #%d: false\n",i+1); } } return 0; }
问题 G: 数字分类 (20)
解题思路
从一开始模拟整个过程就好了,没那么复杂。
#include<cstdio> int main(){ int n; while(scanf("%d",&n) != EOF){ bool flag[5] = {0},flag1= 0; int a[5] = {0}; double a3 = 0; while(n--){ int temp; scanf("%d", &temp); switch(temp % 5){ case 0: if(temp % 2 == 0) a[0] += temp,flag[0] = 1; break; case 1: flag[1] = 1; if(flag1) a[1] -= temp,flag1 = 0; else a[1] += temp,flag1 = 1; break; case 2: flag[2] = 1; a[2]++; break; case 3: flag[3] = 1; a3 += temp; a[3] ++; break; case 4: flag[4] = 1; if(a[4] < temp) a[4] = temp; break; default: break; } } if(a[3]) a3 /= a[3]; for(int i = 0;i < 3;++i) if(flag[i]) printf("%d ",a[i]); else printf("N "); if(a[3]) printf("%.1f ",a3); else printf("N "); if(flag[4]) printf("%d\n",a[4]); else printf("N\n"); } return 0; }
问题 H: 部分A+B (15)
解题思路
就是看给定串内有多少个对应元素呗。
为了防止超过数据范围,结果直接用了long long 保存。int就算无符号也最多是8x108左右,不太行。
#include<cstdio> int main(){ char a[12],b[12]; int da, db; while(scanf("%s %d %s %d", a, &da, b, &db) != EOF){ long long ansa = 0, ansb = 0; for(int i = 0;a[i];++i) if(a[i] == '0' + da) ansa *= 10, ansa += da; for(int i = 0;b[i];++i) if(b[i] == '0' + db) ansb *= 10, ansb += db; printf("%lld\n", ansa + ansb); } return 0; }
问题 I: 锤子剪刀布 (20)
解题思路
这道题,有点复杂。。。。。大概分几步
读入数据的同时统计输赢和统计赢得那个人的手势
然后按照要求输出酒哈了
注意:输赢信息保存一份就好,输出的时候倒序输出就是另外一个人的信息0.0
#include<cstdio> int main(){ char ans[4] = "BCJ"; int n, ansa[3], ansb[3], ans_sum[3]; while(scanf("%d",&n) != EOF){ //重置数组 for(int i = 0;i < 3;i++) ansa[i] = 0 ,ansb[i] = 0, ans_sum[i] = 0; while(n--){ char tempa,tempb; scanf("\n%c %c",&tempa,&tempb); int i,j; for(i = 0;i < 3;i++) if(ans[i] == tempa) break; for(j = 0;j < 3;j++) if(ans[j] == tempb) break; if(i + 1 == j || j + 2 == i) ans_sum[0]++,ansa[i]++; else if(i == j) ans_sum[1] ++; else ans_sum[2]++,ansb[j]++; //printf("%c %c %d %d\n",tempa,tempb,i,j); } int max1 = 0, max2 = 0; for(int i = 1;i < 3;i++){ if(ansa[max1] < ansa[i]) max1 = i; if(ansb[max2] < ansb[i]) max2 = i; } printf("%d %d %d\n%d %d %d\n%c %c\n",ans_sum[0],ans_sum[1],ans_sum[2],ans_sum[2],ans_sum[1],ans_sum[0],ans[max1],ans[max2]); } return 0; }
B1001 害死人不偿命的(3n+1)猜想 (15 分)
地址:B1001 害死人不偿命的(3n+1)猜想 (15 分)
解题思路
按照要求进行操作并计数就好了。
#include<cstdio> int main(){ int n, step = 0; scanf("%d",&n); while(n != 1){ if(n %2 == 1) n = (3 * n + 1) / 2; else n = n/2; step++; } printf("%d\n",step); return 0; }
1011 A+B 和 C (15 分)
地址:1011 A+B 和 C (15 分)
解题思路
因为溢出问题简单的作为long long作为输入来进行判定来解决。平时一定要注意输入输出的判定呀。。
#include<cstdio> int main(){ int n; scanf("%d",&n); for(int i = 0;i < n;i++){ long long a, b, c; scanf("%lld %lld %lld", &a, &b, &c); a + b > c ? printf("Case #%d: true\n",i + 1) : printf("Case #%d: false\n",i + 1); } return 0; }
1046 划拳 (15 分)
地址:1046 划拳 (15 分)
解题思路
根据喊和划的数字来判断是否猜中,然后再根据是否只有一个猜中来增加结果统计。
#include<cstdio> int main(){ int n,han_a,hua_a,sum_a=0,han_b,hua_b,sum_b=0; scanf("%d",&n); while(n--){ scanf("%d %d %d %d",&han_a,&hua_a,&han_b,&hua_b); if(hua_a==(han_a+han_b)){ if(hua_b!=(han_a+han_b)) sum_b++; } else if(hua_b==(han_a+han_b)) sum_a++; } printf("%d %d\n",sum_a,sum_b); return 0; }
1008 数组元素循环右移问题 (20 分)
地址:1008 数组元素循环右移问题 (20 分)
解题思路
先将所有元素右移对应的位数,然后再将前m位写回就好了。
#include<cstdio> int main(){ int n, m; scanf("%d %d", &n, &m); m %= n; int num[n + m]; for(int i = 0;i < n;i++) scanf("%d",&num[i]); //双指针移动 for(int i = m + n - 1,j = n - 1;j >= 0;i--,j--) num[i] = num[j]; for(int i = 0; i < m; i++)//写回 num[i] = num[i + n]; printf("%d",num[0]); for(int i = 1;i < n;i++) printf(" %d",num[i]); puts(""); return 0; }
B1012 数字分类 (20 分)
地址:B1012 数字分类 (20 分)
解题思路
按照题目要求依次进行数字的统计和最后的输出就好了。
#include<cstdio> int main(){ int num,A1=0,A2=0,A3=0,A5=0,n,A2_i=2; float A4=0,A4_num=0; scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%d",&num); switch(num%5){ case 0:if(num%2==0) A1+=num;break; case 1:A2_i%2==0?A2+=num:A2-=num;A2_i++;break; case 2:A3++;break; case 3:A4_num++;A4+=num;break; case 4:num>A5?A5=num:A5=A5;break; } } A4=A4/A4_num; A1>0?printf("%d ",A1):printf("N "); A2_i>2?printf("%d ",A2):printf("N "); A3>0?printf("%d ",A3):printf("N "); A4>0?printf("%.1f ",A4):printf("N "); A5>0?printf("%d\n",A5):printf("N\n"); return 0; }
B1018 锤子剪刀布 (20 分)
地址:B1018 锤子剪刀布 (20 分)
解题思路
这个题目比较复杂,可以利用字符串来转化所有的出拳为0、1、2然后+1就是对应的输赢位置。
#include<cstdio> int main(){ char ans[4] = "BCJ"; int n, ansa[3], ansb[3], ans_sum[3]; while(scanf("%d",&n) != EOF){ //重置数组 for(int i = 0;i < 3;i++) ansa[i] = 0 ,ansb[i] = 0, ans_sum[i] = 0; while(n--){ char tempa,tempb; scanf("\n%c %c",&tempa,&tempb); int i,j; for(i = 0;i < 3;i++) if(ans[i] == tempa) break; for(j = 0;j < 3;j++) if(ans[j] == tempb) break; if(i + 1 == j || j + 2 == i) ans_sum[0]++,ansa[i]++; else if(i == j) ans_sum[1] ++; else ans_sum[2]++,ansb[j]++; //printf("%c %c %d %d\n",tempa,tempb,i,j); } int max1 = 0, max2 = 0; for(int i = 1;i < 3;i++){ if(ansa[max1] < ansa[i]) max1 = i; if(ansb[max2] < ansb[i]) max2 = i; } printf("%d %d %d\n%d %d %d\n%c %c\n",ans_sum[0],ans_sum[1],ans_sum[2],ans_sum[2],ans_sum[1],ans_sum[0],ans[max1],ans[max2]); } return 0; }
A1042 Shuffling Machine (20 分)
地址:A1042 Shuffling Machine (20 分)
解题思路
直接做转换,为了将1-13号牌映射到0-12 对所有序号进行-1操作,这样可以利用取余得到花色,最终的序号输出的时候需要进行+1。
#include<cstdio> const int N=54; char mp[5]={'S','H','C','D','J'}; int start[N+1],end[N+1],next[N+1]; int main(){ int k; scanf("%d",&k); for(int i=1;i<=N;i++) start[i]=i; for(int i=1;i<=N;i++) scanf("%d",&next[i]); while(k--) { for(int i=1;i<=N;++i) end[next[i]]=start[i]; for(int i=1;i<=N;++i) start[i]=end[i]; } for(int i=1;i<=N;i++){ if(i!=1) printf(" "); end[i]--; printf("%c%d",mp[end[i]/13],end[i]%13+1); } printf("\n"); return 0; }
A1046 Shortest Distance (20 分)
地址:A1046 Shortest Distance (20 分)
解题思路
利用前缀和做简化,优化到O(1)的查询复杂度。
#include<cstdio> #include<algorithm> using namespace std; const int MAXN=100005; int dis[MAXN],A[MAXN]; int main(){ int sum=0,query,n,left,right; scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d",&A[i]); sum+=A[i]; dis[i]=sum;//前缀和 } scanf("%d",&query); while(query--){ scanf("%d %d",&left,&right); if(left>right) swap(left,right); int temp=dis[right-1]-dis[left-1]; printf("%d\n",min(temp,sum-temp));//对比结果输出 } return 0; }
A1065 A+B and C (64bit) (20 分)
地址:A1065 A+B and C (64bit) (20 分)
解题思路
直接计算结果,根据结果和原始数据的情况来进行溢出判断,生成最终的结果。
#include<cstdio> int main(){ int T,tcase=1; scanf("%d",&T); while(T--){ long long a,b,c; scanf("%lld %lld %lld",&a,&b,&c); long long res=a+b; bool flag; if(a>0&&b>0&&res<0) flag=true;//上溢 必然大于 else if(a<0&&b<0&&res>=0) flag=false; //下溢必然小于 else if(res>c) flag=true;//无溢出正常比较 else flag=false; flag==true?printf("Case #%d: true\n",tcase++):printf("Case #%d: false\n",tcase++); } return 0; }
B1010 一元多项式求导 (25 分)
地址:B1010 一元多项式求导 (25 分)
解题思路
其实就是很简单的公式,但是注意特殊情况,另外,这道题的判定方式应该是多次运行的。所以没加多余的!= EOF。
#include<cstdio> int main(){ int n=1,a,e; while(scanf("%d %d",&a,&e)!=EOF){ if(e!=0){ if(n!=1){ printf(" "); } printf("%d %d",a*e,e-1); n++; } } if(n==1) printf("0 0"); printf("\n"); return 0; }
1002 A+B for Polynomials (25 分)
地址:1002 A+B for Polynomials (25 分)
解题思路
直接用hash表来存储对应指数的系数就好了,不复杂。
#include<cstdio> const int max_n=1111; double p[max_n]={0}; int main(){ int k,n,count=0; double a; scanf("%d",&k); count+=k; for(int i=0;i<k;i++){ scanf("%d %lf",&n,&a); p[n]+=a; } scanf("%d",&k); count+=k; for(int i=0;i<k;i++){ scanf("%d %lf",&n,&a); if(p[n]!=0) count--; p[n]+=a; if(p[n]==0) count--; } printf("%d",count); for(int i=max_n;i>=0;i--) if(p[i]!=0) printf(" %d %.1f",i,p[i]); printf("\n"); return 0; }
1009 Product of Polynomials (25 分)
地址:1009 Product of Polynomials (25 分)
解题思路
接收所有的第一个的指数和系数,第二个每次接收的时候都和之前的所有数相乘等到结果保存到ans就好了。
#include<cstdio> struct Poly{ int exp;//指数 double cof;//系数 }Poly[1001]; double ans[2001]={0.0}; int main(){ int n,m,number=0; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d %lf",&Poly[i].exp,&Poly[i].cof); scanf("%d",&m); for(int i=0;i<m;i++){ int exp; double cof; scanf("%d %lf",&exp,&cof); for(int j=0;j<n;j++) { if(ans[exp+Poly[j].exp]==0.0) number++; ans[exp+Poly[j].exp]+=(cof*Poly[j].cof); if(ans[exp+Poly[j].exp]==0.0) number--; } } printf("%d",number); for(int i=2000;i>=0;--i){ if(ans[i]!=0.0) printf(" %d %.1f",i,ans[i]); } printf("\n"); }