week6
Day 1
蓝桥杯模拟赛 3
A-[蓝桥杯 2021 省 B2] 特殊年份
思路:直接比较每个数的个十百千位
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int N=1e5+5,M=2e5+5,INF=0x3f3f3f3f; int s[5],ans; int main(){ int a,b,c,d; for(int i=0;i<5;++i){ cin>>s[i]; a=s[i]/1000,b=s[i]/100-a*10,c=s[i]/10-a*100-b*10,d=s[i]%10; if(a==c&&b+1==d)ans++; } cout<<ans; return 0; }
B-[蓝桥杯 2021 省 AB2] 小平方
思路:暴力枚举
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+5,M=2e5+5,INF=0x3f3f3f3f; int n,ans; int main(){ cin>>n; int m=(n+1)/2; for(int i=1;i<n;++i){ if(((i*i)%n)<m)ans++; } cout<<ans; return 0; }
C-[蓝桥杯 2021 省 AB] 砝码称重
思路:每种砝码有三种取法:加上、不选、减去,dp[i][j]表示在前i个砝码中是否能选出总量为j的选法,dp[0][0]=true;
存在其中任意一种状态表示存在该种选法:1.不选:dp[i][j]=dp[i-1][j] 2.加上:dp[i][j]=dp[i-1][j-w[i]] 3.减去:dp[i][j]=dp[i-1][j+w[i]]
由于总量存在负数,所有总量加上迁移量N
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; const int N=2e5+10; int n,m,x,w[110]; bool f[110][N]; int main() { cin.tie(0),cout.tie(0); cin>>n; for(int i=1;i<=n;++i){ cin>>w[i]; m+=w[i]; } f[0][N/2]=true; for(int i=1;i<=n;++i){ for(int j=-m;j<=m;++j){ f[i][j+N/2]=f[i-1][j+N/2]; if(j-w[i]>=-m)f[i][j+N/2]|=f[i-1][j-w[i]+N/2]; if(j+w[i]<=m)f[i][j+N/2]|=f[i-1][j+w[i]+N/2]; } } int res=0; for(int i=1;i<=m;++i) if(f[n][i+N/2])res++; cout<<res; return 0; }
D-[蓝桥杯 2021 省 AB2] 完全平方数
思路:完全平方数的质因子成对出现,消去所有成对的质因子,剩余的质数即为答案
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+5,M=2e5+5,INF=0x3f3f3f3f; ll n; int main(){ cin>>n; for(ll i=2;i*i<=n;++i){ while(n%(i*i)==0){n/=(i*i);} } cout<<n; return 0; }
E-[蓝桥杯 2021 省 B] 时间显示
思路:每天的时分秒数相同,算出有多少时分秒
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+5,M=2e5+5,INF=0x3f3f3f3f; ll n; int main(){ cin>>n; ll h,m,s; n/=1000; h=n/3600%24; m=n/60%60; s=n%60; if(h<10)cout<<0; cout<<h<<':'; if(m<10)cout<<0; cout<<m<<':'; if(s<10)cout<<0; cout<<s; return 0; }
F-[蓝桥杯 2021 省 B] 杨辉三角形
思路:画个图斜着看,每斜的第一个数是第C(2k,k)个,大小递增;k最大为16,C(32,16)>=1e9;每斜二分找出满足C(s,k)大于等于n的最小的s,若C(s,k)等于n,即为该位置;答案为s*(1+s)/2+(k+1)
1 ---> C(0, 0) 1 1 2 ---> C(2, 1) 1 3 ---> C(2n, n) 1 4 6 ---> C(4, 2) 1 5 10 1 6 15 20 ---> C(6, 3)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=2e5+10; int n; ll C(int a,int b){ ll res=1; for(int i=a,j=1;j<=b;++j,--i){ res=res*i/j; if(res>n)return res; } return res; } bool check(int k){ int l=2*k,r=max(n,l); while(l<r){ int mid=l+r>>1; if(C(mid,k)>=n)r=mid; else l=mid+1; } if(C(r,k)!=n)return false; cout<<1ll*(r+1)*r/2+k+1; return true; } int main() { cin.tie(0),cout.tie(0); cin>>n; for(int k=16;k>=0;--k){ if(check(k))break; } return 0; }
G-[蓝桥杯 2021 省 A] 左孩子右兄弟
思路:答案为一点的最深子树的深度加上该点孩子数的最大值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5,M=2e5+5,INF=0x3f3f3f3f; int n; vector<int>g[N]; int dfs(int u){ int s=g[u].size(),ans=0; for(int i=0;i<g[u].size();++i){ ans=max(ans,dfs(g[u][i])+s); } return ans; } int main(){ cin>>n; int x; for(int i=2;i<=n;++i){ cin>>x; g[x].push_back(i); } int ans=dfs(1); cout<<ans; return 0; }
H-[蓝桥杯 2021 省 AB2] 负载均衡
思路:堆模拟,每台计算机正运算的任务按完成时间从小到大排序,同时记录消耗算力,每次比较该任务的开始时刻,将已完成的任务除去,并恢复算力
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; const int N=2e5+5; int n,m,s[N]; priority_queue<PII,vector<PII>,greater<PII>> q[N]; int main() { cin.tie(0),cout.tie(0); cin>>n>>m; int a,b,c,d; for(int i=1;i<=n;++i){ cin>>s[i]; } while(m--){ cin>>a>>b>>c>>d; while(q[b].size()&&a>=q[b].top().first){ s[b]+=q[b].top().second; q[b].pop(); } if(d>s[b])cout<<"-1\n"; else{ q[b].push({c+a,d}); s[b]-=d; cout<<s[b]<<'\n'; } } return 0; }
Day 3
SMU Winter 2023 Round #11 (Div.2)
A-BCD
思路:向上整除
B-Poku's Vacation
思路:求满足1+2+...+x的和小于等于n的最大x
C-Dualites in Pain - The Beginning
思路:若第二大的数等于最大的数或差值为1则YES;或者像H题反向模拟
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e5+5,INF=1e9,M=1e3+10; int n,a[105]; int main(){ cin>>n; for(int i=0;i<n;++i)cin>>a[i]; sort(a,a+n); if(a[n-1]==a[n-2]||a[n-1]-1==a[n-2])cout<<"YES"; else cout<<"NO"; return 0; }
D-Elder Ning
思路:每个怪都能杀才满足,枚举出最小左界和最大右界,界限成立则输出个数
E-Hostel Cleaning
思路:条件是个数少,接着是价格少,所有分为k类,每类累加求最小
F-No Internet IPC!
思路:每次连接好2n-1个,每次取min(限制,2n-1)进行累加,连接总数满足条件时的次数为答案
G-Dualites in Pain - The Conclusion
思路:每种课的次数x,存在的更新状态有x种:x、x-1、...、2、1,将所有更新状态存入单调队列,每种状态按位置的先后排序,按状态接着位置依次输出
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e5+5,INF=1e9,M=1e3+10; int n,a[105]; int main(){ vector<int>ve[1001]; cin>>n; for(int i=1;i<=n;++i){ cin>>a[i]; int x=a[i]; while(x){ ve[x--].push_back(i); } } sort(a+1,a+n+1); if(a[n]==a[n-1]||a[n]-1==a[n-1]){ for(int i=1000;i>=1;--i){ for(auto w:ve[i]) cout<<w<<' '; } } else cout<<-1; return 0; }
H-Perfect Array
思路:反向模拟出答案,倒叙枚举,若当前q-th等于q则取出作为最后一步的数字
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e5+5,INF=1e9,M=1e3+10; int n; vector<int> ve,ans; int main(){ cin>>n; int x; for(int i=0;i<n;++i){ cin>>x; ve.push_back(x); } vector<int>c; while(ans.size()!=n){ c.clear(); bool ok=false; for(int i=ve.size()-1;i>=0;--i){ if(!ok&&ve[i]==i+1){ ans.insert(ans.begin(),ve[i]);ok=true; continue; } c.insert(c.begin(),ve[i]); } if(c.size()==ve.size()){ cout<<"NO"; return 0; } ve.clear(); ve=c; } cout<<"YES\n"; for(auto t:ans)cout<<t<<' '; return 0; }
Day 5
SMU Winter 2023 Round #12 (Div.2)
A - KK 画猪
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e4+5,INF=1e9,M=1e3+10; int main(){ cin.tie(0),cout.tie(0); string a; cin>>a; cout<<" (\\____/)\n" " / @__@ \\\n" " ( (oo) )\n" " `-.~~.-'\n" " / \\\n" " @/ \\_\n" "(/ / \\ \\)\n" " WW`----'WW"; return 0; }
B - KK 学几何
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e4+5,INF=1e9,M=1e3+10; int n,t,r,l,h,w; double s; int main(){ cin.tie(0),cout.tie(0); cin>>n; while(n--){ cin>>t; if(t==1){ cin>>r; s=s+double(3*r*r); } else if(t==2){ cin>>l>>h; s=s+double(l*h)/2; } else if(t==3){ cin>>l>>w; s=s+double(l*w); } } cout << fixed << setprecision(1)<<s; return 0; }
C - KK 算日期
思路:不算0元年,n+m小于0时绝对值加一
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e4+5,INF=1e9,M=1e3+10; int t,n,m; int main(){ cin.tie(0),cout.tie(0); cin>>t; while(t--){ cin>>n>>m; n+=m; if(n<=0){ n=abs(n); n++; } if(n%4==0&&n%100!=0||n%400==0)cout<<29<<'\n'; else cout<<28<<'\n'; } return 0; }
D - KK 与卡牌
思路:将武力值转化为整数,kk的所有卡牌按武力值大小分别存储名字,每种武力值的名字按字典序排序,用前缀和求出大于该武力值的卡牌个数,当物理值相等时,二分求出字典序小于该名字的卡牌,求出其个数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e4+5,INF=1e9,M=1e3+10; int n,t,r,l,h,w; double s; int main(){ cin.tie(0),cout.tie(0); cin>>n; while(n--){ cin>>t; if(t==1){ cin>>r; s=s+double(3*r*r); } else if(t==2){ cin>>l>>h; s=s+double(l*h)/2; } else if(t==3){ cin>>l>>w; s=s+double(l*w); } } cout << fixed << setprecision(1)<<s; return 0; }
E - KK 与答辩
思路:每个人参加的场数等于分数小于kk的场数即满足条件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e4+5,INF=1e9,M=1e3+10; int t,n,a,cnt[105]; map<string,int>ma,mb; int main(){ cin.tie(0),cout.tie(0); cin>>t; while(t--){ int res=0; ma.clear(); mb.clear(); cin>>n; while(n--){ cin>>a; string ss[10]; int b,c,kk; for(int i=0;i<a;++i){ cin>>ss[i]>>b>>c; mb[ss[i]]++; if(i==0)kk=b+c; if(i!=0&&b+c<kk)ma[ss[i]]++; } } for(auto t:mb){ if(ma[t.first]==t.second)res++; } cout<<res<<'\n'; } return 0; }
F-KK 与刷题
思路:更新到ai为止每个数出现的个数,算出[1,ai-1]区间的数的个数和,用线段树计算;
线段树
这是个结构体数组。
数字是数组下标,[ i,j]表示i~j区间的数据和;
添加一个数a,从1节点开始向下,直到[l,r]的l=r=a;
查找一个数a,求[1,a-1]从1节点开始向下,有三种情况:[1,a-1]在左孩子范围之内、[1,a-1]在右孩子范围之内、两边都包含
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e5+1,INF=1e9,M=1e5+10; struct sc{ int l=1,r=0; int v=0; }s[3*N]; void init(){ s[1].l=1,s[1].r=100000; queue<int> q; q.push(1); while(s[q.front()].l!=s[q.front()].r){ int size=q.size(); for(int i=0;i<size;++i){ int mid=(s[q.front()].l+s[q.front()].r)>>1; s[q.front()*2].l=s[q.front()].l,s[q.front()*2].r=mid; s[q.front()*2+1].l=mid+1,s[q.front()*2+1].r=s[q.front()].r; q.push(q.front()*2); q.push(q.front()*2+1); q.pop(); } } } int solve(int h,int v1,int v2){ int l=s[h].l,r=s[h].r,mid=l+r>>1,sum=0; if(v1<=l&&v2>=r)sum+=s[h].v; else if(mid>=v2)sum= solve(2*h,v1,v2); else if(mid<v1)sum= solve(2*h+1,v1,v2); else sum= solve(2*h,v1,mid)+ solve(2*h+1,mid+1,v2); return sum; } int main(){ cin.tie(0),cout.tie(0); int n,a,ans=0,ma=0; cin>>n; init(); for(int i=0;i<n;++i){ cin>>a; ll ll=1; while(s[ll].l!=s[ll].r){ int mid=s[ll].l+s[ll].r>>1; s[ll].v++; if(a<=mid)ll*=2; else ll=ll*2+1; } s[ll].v++; int same=s[ll].v; int less=solve(1,1,a-1); int more=i+1-same-less; int t=less-more; ans+=t; ma=max(ma,ans); } cout<<ma<<' '<<ans; return 0; }
G - KK 看跳舞
思路:将所有序列看作倒序,则将除了1到n外,将存在正序的序列倒转,再将n前的数插进末尾后判断序列是否倒序即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e4+5,INF=1e9,M=1e3+10; int t,n; vector<int>a; int main(){ cin.tie(0),cout.tie(0); cin>>t; while(t--){ a.clear(); a.push_back(0); cin>>n; int x,sn; for(int i=1;i<=n;++i){ cin>>x; a.push_back(x); if(x==n)sn=i; } if(a[1]+1==a[2]||a[2]+1==a[3]){ reverse(a.begin()+1, a.end()); sn=n-sn+1; } vector<int>b; b.push_back(0); for(int i=sn;i<=n;++i)b.push_back(a[i]); for(int i=1;i<sn;++i)b.push_back(a[i]); bool ok=true; for(int i=1;i<=n;++i){ if(b[i]!=b[i+1]+1&&i+1<=n){ ok=false;break; } } if(ok)cout<<"YES\n"; else cout<<"NO\n"; } return 0; }
H - KK 与十佳
思路:存在负数的情况下,若无正数,负数个数为奇则输出最大负数,负数个数为偶则输出最小负数;若有正数,负数个数为偶则输出最小正数,负数个数为奇数则输出最大负数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e4+5,INF=1e9,M=1e3+10; int n,fm=-INF,fmi,fc,zx=INF,zc; int main(){ cin.tie(0),cout.tie(0); cin>>n; int x; for(int i=0;i<n;++i){ cin>>x; if(x<0){ fm=max(fm,x); fmi=min(fmi,x); fc++; } else{ zx=min(zx,x); zc++; } } if(zc==0){ if(fc%2==0)cout<<fmi; else cout<<fm; return 0; } if(fc==0){ cout<<zx; return 0; } if(fc%2==0)cout<<zx; else cout<<fm; return 0; }
I - KK 买股票
思路:记录下前i个数中最小的数,枚举第i个数与前i-1的数中最小值的差,求最大
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e5+5,INF=1e9,M=1e3+10; int n,a[N],s[N]; int main(){ cin.tie(0),cout.tie(0); cin>>n; s[0]=INF; int res=0; for(int i=1;i<=n;++i){ cin>>a[i]; s[i]=min(s[i-1],a[i]); if(i>1){ res=max(res,a[i]-s[i-1]); } } cout<<res; return 0; }
J - KK与英语
思路:将is变为was,且前后有空格
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e5+5,INF=1e9,M=1e3+10; string s; int main(){ cin.tie(0),cout.tie(0); getline(cin,s); for(int i=1;i<s.size()-2;++i){ if(s[i]=='i'&&s[i+1]=='s'&&s[i-1]==' '&&s[i+2]==' ') s.replace(i,2,"was"); } cout<<s; return 0; }
K-KK 与线代
思路:求出行列式等式-2028-442*x
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e3+5,INF=1e9,M=1e3+10; int l,r; int main(){ cin.tie(0),cout.tie(0); cin>>l>>r; ll s; s=max(r,l); ll res=-2028-442*s; cout<<res; return 0; }
L-KK 学五子棋
思路:
对于每个0的位置,若满足下2后连成5个2则Win,若满足下2后刚好阻止5个1一条线且只存在一个2满足则Defense,存在多个则Defeated,若不能使2赢,也不能让1赢,则Defense
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; typedef long long ll; const int N=1e3+5,INF=1e9,M=1e5+10; int t,n,m; int d[N][N]; int a[N][N]; bool st[N][N]; int dx[8]= {-1,-1,0,1,1,1,0,-1}; int dy[8]= {0,1,1,1,0,-1,-1,-1}; int f(int u,int x,int y){ int ans=0; int xx,yy; for(int i=0;i<4;++i){ int res=0; xx=x+dx[i],yy=y+dy[i]; while(xx>=0&&xx<n&&yy>=0&&yy<m&&a[xx][yy]==u){ res++; xx+=dx[i],yy+=dy[i]; } xx=x+dx[i+4],yy=y+dy[i+4]; while(xx>=0&&xx<n&&yy>=0&&yy<m&&a[xx][yy]==u){ res++; xx+=dx[i+4],yy+=dy[i+4]; } ans=max(ans,res); if(ans>=4)break; } return ans; } int main(){ cin.tie(0),cout.tie(0); cin>>t; while(t--){ cin>>n>>m; memset(st,false,sizeof st); int xx,yy; bool ok3=true; for(int i=0;i<n;++i) for(int j=0;j<m;++j) cin>>a[i][j]; memset(d,0,sizeof d); bool ok1=true,ok2=true; int x1,y1,x2,y2,cn2=0; for(int i=0;i<n;++i){ for(int j=0;j<m;++j){ if(a[i][j]==0){ if(ok3){ xx=i,yy=j;ok3=false; } if(f(2,i,j)>=4){ x1=i,y1=j; ok1=false;break; } if(f(1,i,j)>=4){ x2=i,y2=j;cn2++; ok2=false; } } } if(!ok1)break; } if(!ok1){ cout<<"Win\n"<<x1+1<<' '<<y1+1<<'\n'; } else if(!ok2){ if(cn2==1) cout<<"Defense\n"<<x2+1<<' '<<y2+1<<'\n'; else cout<<"Defeated\n"; } else{ cout<<"Defense\n"<<xx+1<<' '<<yy+1<<'\n'; } } return 0; }