L1-002 打印沙漏 (20 分)
不算沙漏下面,上面部分随着行数增加,字符的总数依次是1,4,9,16…满足row2×2-1<=n,逆推得上半部分行数(算上1)row=sqrt((n+1)/2),行最大字符数=2×row-1。剩下的for循环实现。
L1-003 个位数统计 (15 分)
用map和数组统计,可以直接char数组,和dodo那题字符类型的通用了(例如按字典序输出一行英文句子每个单词的出现个数)
ps:pta用不了gets,可以改用cin.getline
#include
using namespace std;
int main()
{
char a[1005];
mapmp;
cin.getline(a,1005);
int len=strlen(a);
for(int i=0;i
map::iterator it;
for(it=mp.begin();it!=mp.end();it++)
cout return 0; } L1-006 连续因子 (20 分) 看数据范围,暴力肯定不行,就一边2~sqrt(n)遍历试根一边求区间并更新起始点和最大区间长度。注意:1不算在序列内,所以要从2开始 #include #define ll long long using namespace std; const int maxn=1e5+5; ll n,len=0,st,maxx=0; int main() { cin>>n; for(ll i=2;i<=sqrt(n);i++) { ll x=n,xi=i,len=0; while(x%xi==0)//一旦试根成功就求区间 { x=x/xi; xi++; len++; } if(len>maxx) //必须是> 不能是>= { //因为要保证是最长的同时是最小序列,即st要最小 maxx=len; st=i; } } if(maxx==0) printf("1\n%lld",n); //考虑质数情况 序列即本身 else { cout< for(int i=1;i<=maxx;i++) { if(i==1) printf("%lld",st); else printf("*%lld",st); st++; } } return 0; } L1-009 N个数求和 (20 分) 因为没开ll白花了半个小时…老经典了。通分 —> 特判t==1 —> 特判和为0 —> 约分 —> 判断符号 —> 分离整数 —> 根据分离后结果处理输出形式。注意:如果和为负数 ,那么之后分离整数时整数和分子都要自带负号 。 #include #define ll long long using namespace std; const int maxn=1e5+5; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; } struct Rational { ll n,d; }num[105]; ll mod,fz,fm,zs; int main() { ll t,fh=1; cin>>t; for(ll i=1;i<=t;i++) scanf("%lld/%lld",&num[i].n,&num[i].d); if(t==1) { if(num[1].n==0) { printf("0"); return 0; } mod=gcd(abs(num[1].n),abs(num[1].d)); fz=num[1].n/mod; fm=num[1].d/mod; fh=fz/abs(fz); if(abs(fz)>=fm) { fh?zs=fz/fm:zs=-fz/fm; fz=fz%fm; } if(fz==0) printf("%lld",zs); else abs(zs)?printf("%lld %lld/%lld",zs,fz,fm):printf("%lld/%lld",fz,fm); return 0; } for(ll i=1;i<=t-1;i++) { fm=num[i].d*num[i+1].d; fz=num[i].n*num[i+1].d+num[i+1].n*num[i].d; num[i+1].n=fz; num[i+1].d=fm; } if(fz==0) { printf("0"); return 0; } mod=gcd(abs(fz),abs(fm)); fm/=mod; fz/=mod; fh=(fm/abs(fm))*(fz/abs(fz)); if(abs(fz)>=fm) { fh?zs=fz/fm:zs=-fz/fm; fz=fh*abs(fz)%fm; } if(abs(fz)==0) printf("%lld",zs); else abs(zs)?printf("%lld %lld/%lld",zs,fz,fm):printf("%lld/%lld",fz,fm); return 0; } L1-017 到底有多二 (15 分) 遍历字符串。注意:倍数是初始值为1,负数则再乘1.5,要是还是偶数则再乘2.0,例如负偶数的倍数=1×1.5×2.0,负奇数的倍数=1×1.5,正偶数的倍数=1×2.0 L1-025 正整数A+B (15 分) 有很多细节要注意,①读取 ②如果是数字还得要求在区间内 ③有一种很坑的情况,例如:【输入:1 1 1】【输出:1 + ? = ?】而不是【1 + 1 = 2】或【? + ? = ?】!!! 我自己的代码很繁琐 #include #define ll long long using namespace std; const int maxn=1e3+5; char a[maxn],b[maxn],ch; int t=1,aa=0,bb=0,flaga=1,flagb=1,x=0,y=0;; bool judge(char ch) { if(ch>='0'&&ch<='9') return true; else return false; } int main() { while(scanf("%c",&ch)) { if(t==1) { if((aa==0&&(!judge(ch)||ch=='0'))||(!judge(ch)&&ch!=' ')) flaga=0; else if(flaga&&ch!=' ') a[aa++]=ch; } if(t==2) { if((bb==0&&!judge(ch))||(!judge(ch)&&ch!=' '&&ch!='\n')) flagb=0; else if(flagb&&ch!='\n') b[bb++]=ch; } if(ch==' ') t++; if(ch=='\n') break; } if(t>2) flagb=0; if(flaga==0) printf("? + "); else { for(int i=0;i if(x>=1&&x<=1000) printf("%s + ",a); else { printf("? + "); flaga=0; } } if(flagb==0) printf("? = "); else { for(int i=0;i if(y>=1&&y<=1000) printf("%s = ",b); else { printf("? = "); flagb=0; } } if(flaga*flagb==0) printf("?"); elseprintf("%d",x+y); return 0; } 看到一个比我少一半代码量的码,可以参考一下。要巧用字符串,也要写得干净利落,学习学习。 #include using namespace std; string a,b; int checkIt(string str){ int sum=0; for(int i=0;i if(isdigit(str[i])){ sum=sum*10+str[i]-'0'; }else{ return -1; } } if(sum>=1&&sum<=1000) return sum; else return -1; } int main(){ cin>>a; getchar(); getline(cin,b); int sumA=checkIt(a); int sumB=checkIt(b); if(sumA==-1) printf("? + "); else printf("%d + ",sumA); if(sumB==-1) printf("? = "); else printf("%d = ",sumB); if(sumA==-1 || sumB==-1) printf("?\n"); else printf("%d\n",sumA+sumB); return 0; } L1-028 判断素数 (10 分) 要特判1不是素数。 判断素数函数: int judge(ll x) { if(x==1) return 0; if(x<=3) return 1; if(x%2==0) return 0; for(ll i=3;i if(x%i==0) return 0; return 1; } ⭐其他判断素数的更优方法(都是1e9范围):高效率判断素数总结 L1-046 整除光棍 (20 分) 因为求出来的数可能很大,所以不可能是通过s来求光棍数。那么就通过光棍数逐位增加的同时来一位位地求出s。其实相当于摆竖式的原理,从高位开始运算,除不尽就多加一位1,循环往复,直到正好整除为止。 #include #define ll long long using namespace std; const int maxn=1e5+5; int x,s,n=0; int main() { scanf("%d",&x); int num=0,flag=0; for(int i=1;;i++) { num=num*10+1; if(num>=x) { s=num/x; printf("%d",s); flag=1; } else if(flag) printf("0"); num=num%x; if(num==0) { printf(" %d",i); break; } } return 0; } L2-032 彩虹瓶 (25 分) 用堆栈模拟一下就行,注意一下now==num后栈顶元素可不可以继续取走,直到没有可取的为止(while实现)。这题模拟赛做到了,很有思路但是因为基础很差,堆栈的一些基本操作忘了,赛后看了眼笔记就过了,所以还是基础要补好,毕竟不能带纸质材料。 #include #define ll long long #define pb push_back using namespace std; const int maxn=1e5+5; int n,m,k; int main() { scanf("%d%d%d",&n,&m,&k); while(k--) { stackst; int num=1,now,flag=1; for(int i=1;i<=n;i++) { scanf("%d",&now); if(now!=num) { st.push(now); if(st.size()>m) flag=0; } else { num++; while(!st.empty()) { if(st.top()==num) { num++; st.pop(); } else break; } } } if(flag!=0&&st.empty()) printf("YES\n"); else printf("NO\n"); } return 0; }