寒假训练第二周
G-天气预报_2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛(重现赛)@IR101 (nowcoder.com)
用到算法(前缀和+尺取法)
题解:实现前缀和求一下某一个段里0和1的数量,分别记录下雨和不下雨天数
然后开始尺取
首先枚举终点一个for 类似双指针思想
然后一个k从前往后跑,直到不符合条件whlie结束,记录k-1个答案,因为符合条件是1到k所以有k-1个区间
然后继续枚举终点不断循环即可
#include <bits/stdc++.h> //#pragma GCC optimize("Ofast") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> //#define double long double #define int long long //#define endl '\n' using namespace std; const int N=1e6+7,M=1e1; const int INF = 0x3f3f3f3f3f3f3f3f; const int mod=998244353; typedef pair<int,int> PII; int kmp(int a,int k,int p) { int ans=1; while (k) { if(k&1) ans=ans*a%p; k>>=1; a=a*a%p; } return ans; } // 快速幂 int ans[N]; int ans1[N]; void solve() { int n,a,b; cin>>n>>a>>b; string s; cin>>s; s=' '+s; for(int i=1;i<=n;i++) { if(s[i]=='1') { ans[i]=ans[i-1]+1; ans1[i]=ans1[i-1]; } else { ans[i]=ans[i-1]; ans1[i]=ans1[i-1]+1; } } int sum=0; int cnt=0; int k=1; for (int i = 1; i <= n; i++) { while (ans[i] - ans[k-1] >= b && ans1[i]-ans1[k-1]>=a && k<=i) { k++; } sum+=k-1; cnt=0; } if(a==0 &&b==0) sum++; cout<<sum<<endl; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; // cin>>T; while(T--){ solve(); } return 0; }
E-Wiki下象棋_2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛(重现赛)@IR101 (nowcoder.com)
图论题:bfs广搜,找最短路
这个直接暴力搜即可,注意的就是,中国的马如果有东西堵着,就不能走,这个特判一下即可,其他直接爆搜(赛时没看,题目一长就怕,简单题可惜了)
#include <bits/stdc++.h> //#pragma GCC optimize("Ofast") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> //#define double long double #define int long long //#define endl '\n' using namespace std; const int N=300+10,M=1e1; const int INF = 0x3f3f3f3f3f3f3f3f; const int mod=998244353; typedef pair<int,int> PII; int k,a,b,c,d; int n,m; int tu[N][N]; int vis[N][N]; int dx[]={-2,-2,2,2,-1,1,-1,1}; int dy[]={-1,1,-1,1,-2,2,2,-2}; struct G { int x,y,se=0; }; int bfs(int op) { memset(vis,0,sizeof vis); queue<G> q; q.push({a,b,0}); vis[a][b]=1; while (q.size()) { G t=q.front(); q.pop(); if(t.x==c && t.y==d) { return t.se; } for(int i=0;i<8;i++) { int xx=t.x+dx[i]; int yy=t.y+dy[i]; if(xx<1 || xx>n || yy<1 || yy>m) continue; if(tu[xx][yy]==1) continue; if(vis[xx][yy]==1) continue; if(op==1) { if(abs(dx[i])==2) { if(tu[t.x+dx[i]/2][t.y]==1) continue; } else { if(tu[t.x][t.y+dy[i]/2]==1) continue; } } q.push({xx,yy,t.se+1}); vis[xx][yy]=1; } } return -1; } void solve() { memset(tu,0,sizeof tu); cin>>n>>m; cin>>k>>a>>b>>c>>d; for(int i=1;i<=k;i++) { int x,y; cin>>x>>y; tu[x][y]=1; } cout<<bfs(0)<<" "<<bfs(1)<<endl; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; cin>>T; while(T--){ solve(); } return 0; }
L-剪绳子_2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛(重现赛)@IR101 (nowcoder.com)
题解:这个可以一个set维护区间然后暴力二分找左右边界即可
需要注意的点
这个就是代表取这个地址上的值,之所以要减减要找的左边界不然就是原地了
然后加下面特判,因为set是红黑树的结构,end地址的值可能不是10,所以我们要特判把10搞出来否则过不了
#include <bits/stdc++.h> //#pragma GCC optimize("Ofast") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> //#define double long double #define int long long //#define endl '\n' using namespace std; const int N=1e6+10,M=1e1; const int INF = 0x3f3f3f3f3f3f3f3f; const int mod=998244353; typedef pair<int,int> PII; set<double> a; void solve() { int q; cin>>q; char k; double f; a.insert(0); a.insert(10); while (q--) { cin>>k; if(k=='C') { cin>>f; a.insert(f); } else { cin>>f; auto l= lower_bound(a.begin(), a.end(),f); auto r= upper_bound(a.begin(),a.end(),f); if(r==a.end())printf("%.5f\n",10-(*--l)); else printf("%.5lf\n",*r-(*--l)); } } } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; // cin>>T; while(T--){ solve(); } return 0; }
7-8 谷歌的招聘 - SMU 2024 winter round1 (pintia.cn)
搞这个题主要目的是学到了一个新的函数
stoi 这个函数可以把字符串数字直接转换成整数,十分便捷get新函数
用法在下面自己看 直接把字符串放进去就好了
//#include <bits/stdc++.h> #include <queue> #include <cmath> //#define double long double #define int long long //#define endl '\n' using namespace std; const int N=1e6+7,M=1e1; const int INF = 0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; typedef pair<int,int> PII; int a[N]; bool isp(int n) { if(n==0 || n==1) { return false; } for(int i=2;i*i<=n;i++) { if(n%i==0) return false; } return true; } void solve() { int l,k; cin>>l>>k; string s; cin>>s; for(int i=0;i<=l-k;i++) { int x=stoi(s.substr(i,k)); if(isp(x)) { cout<<s.substr(i,k)<<endl; return; } } cout<<"404"<<endl; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; // cin>>T; while(T--){ solve(); } return 0; }
E-本题又主要考察了贪心_2024牛客寒假算法基础集训营1 (nowcoder.com)
这道题很简单啊,但是不会爆搜,一直想贪心导致卡了好久
题解:就是你对每一个状态递归爆搜,记得回溯,跑完3个状态就好了会跑出一个最优解即可
#include <bits/stdc++.h> //#pragma GCC optimize("Ofast") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> //#define double long double #define int long long //#define endl '\n' using namespace std; const int N=1e6+10,M=1e1; const int INF = 0x3f3f3f3f3f3f3f3f; const int mod=998244353; typedef pair<int,int> PII; int n,m; int a[N]; int mi; vector<PII> b; void dfs(int u) { if(u == m+1) { int k=1; for(int i=2;i<=n;i++) if(a[i]>a[1]) k++; mi=min(k,mi); return; } int x=b[u-1].first,y=b[u-1].second; a[x]+=3; dfs(u+1); a[x]-=3; a[y]+=3; dfs(u+1); a[y]-=3; a[x]++; a[y]++; dfs(u+1); a[x]--; a[y]--; } void solve() { cin>>n>>m; for(int i=1;i<=n;i++) { cin>>a[i]; } for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; b.push_back({x,y}); } mi=n; dfs(1); cout<<mi<<endl; b.clear(); } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; cin>>T; while(T--){ solve(); } return 0; }
B-关鸡_2024牛客寒假算法基础集训营1 (nowcoder.com)
这道题纯模拟,太恶心了,赛事脑袋太乱,通过一半样例而已
题解:分几种情况一次讨论即可
#include <bits/stdc++.h> //#pragma GCC optimize("Ofast") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> //#define double long double #define int long long //#define endl '\n' using namespace std; const int N=1e6+10,M=1e1; const int INF = 0x3f3f3f3f3f3f3f3f; const int mod=998244353; typedef pair<int,int> PII; PII a[N]; bool cmp(PII x,PII y) { return x.second<y.second; } void solve() { int n; cin>>n; for(int i=0;i<n;i++) { int x,y; cin>>x>>y; a[i]={x,y}; } sort(a,a+n,cmp); bool fu= false,zheng= false; int f=0; int l=0,r=0,x=0; bool ll= false,rr= false; for(int i=0;i<n;i++) { if(a[i].first==2 && a[i].second==0) f++,x=1; if(a[i].first==1 && a[i].second==-1) f++,l=1; if(a[i].first==1 && a[i].second==1) f++,r=1; if (a[i].second < 0) ll = true; if (a[i].second > 0) rr = true; if(i) { if(a[i].second == a[i-1].second) { if(a[i].second<0) fu= true; else zheng= true; } else if(a[i].second-1==a[i-1].second && a[i].first+a[i-1].first==3) { if(a[i-1].second<0) fu= true; else if(a[i].second>0) zheng= true; } } } if((zheng&&fu) || f==3) cout<<0<<endl; else if((zheng && x && l) || (fu && r && x)) cout<<0<<endl; else if (x && l || x && r || l && r) cout<<1<<endl; else if(fu && r || zheng && l || fu && x || zheng && x) { cout<<1<<endl; } else if (fu && rr || zheng && ll) cout<<1<<endl; else if (l && x && rr || r && x && ll) cout<<1<<endl; else if(zheng || fu || x || l || r || (ll&&rr)) cout<<2<<endl; else{ cout<<3<<endl; } } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; cin>>T; while(T--){ solve(); } return 0; }
L-要有光_2024牛客寒假算法基础集训营1 (nowcoder.com)
这道题也是简单嘎,赛时没有看抽象题
题解:画一下图然后就可以看出一个梯形就是最大面积直接相似三角形搞一搞就可以了
#include <bits/stdc++.h> //#pragma GCC optimize("Ofast") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> //#define double long double #define int long long //#define endl '\n' using namespace std; const int N=1e6+10,M=1e1; const int INF = 0x3f3f3f3f3f3f3f3f; const int mod=998244353; typedef pair<int,int> PII; void solve() { int c,d,h,w; cin>>c>>d>>h>>w; cout<<3*w*c<<endl; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; cin>>T; while(T--){ solve(); } return 0; }