Week6

蓝桥杯模拟赛 4

A题 刷题统计

签到题,简单计算一下即可,一周为一个周期

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #include<map> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define int long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; int a, b, n; void solve() { cin >> a >> b >> n; int t = n % (5 * a + 2 * b); int k = n / (5 * a + 2 * b); int ans = 0; int l[] = {a, a, a, a, a, b, b}; for (int i = 0; t > 0; i++)t -= l[i], ans++; cout << ans + k * 7 << endl; } signed main() { IOS; CC; int h_h = 1; //cin >> h_h; while (h_h--) solve(); return 0; }

C题 求和

利用前缀和的知识,每个数和他后面的每个数相乘,提出公因子,剩下的用前缀和求即可。

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #include<map> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define int long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; int s[2*N], a[2*N]; int n, sum, ans; void solve() { cin >> n; for (int i = 1; i <= n; i++)cin >> a[i], s[i] = s[i - 1] + a[i]; for (int i = 1; i <= n; i++)ans += a[i] * (s[n] - s[i]); cout << ans << endl; } signed main() { IOS; CC; int h_h = 1; //cin >> h_h; while (h_h--) solve(); return 0; }

D题 修建灌木

这道题应该是属于找规律,它最高是什么时候呢,就是从这个点开始,移动到头或尾,再折回来到这点所经过的距离,左右两边求最大值即可。

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #include<map> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define int long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; int s[2*N], a[2*N]; int n, sum, ans; void solve() { cin >> n; for (int i = 0; i < n; i++) { cout << max(2 * i, 2 * (n - 1 - i)) << endl; } } signed main() { IOS; CC; int h_h = 1; //cin >> h_h; while (h_h--) solve(); return 0; }

E题 李白打酒加强版

这是一道动态规划的题目,我们可以先定义一下集合的含义,dp[i][j][k] 表示为前i次,有j次遇到店,剩下酒为k斗。因为n,m最大值为100,因此当k>100之后,该情况必然不合法。

#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 110, MOD = 1e9 + 7; int n, m; int f[N][N][N]; int main() { cin >> n >> m; f[0][0][2] = 1; for (int i = 0; i <= n; i ++ ) for (int j = 0; j <= m; j ++ ) for (int k = 0; k <= m; k ++ ) { int& v = f[i][j][k]; if (i && k % 2 == 0) v = (v + f[i - 1][j][k / 2]) % MOD; if (j) v = (v + f[i][j - 1][k + 1]) % MOD; } cout << f[n][m - 1][1] << endl; return 0; }

H题 卡牌

容易知道是把空白牌用到少的类上,这题思路就是直接二分答案了\n\n如果当前类牌不够mid张,当然是将空白的编变成该类牌,一是看是否超过了b数组的限制,二是看是否超过了最大空白牌数量。\n\n直到最后也是没有被返回NO,那么返回YES

#include<bits/stdc++.h> using namespace std; #define LL long long #define M 1000005 LL n,m; LL a[M],b[M]; int check(int mid){ LL sum=0; for(int i=1;i<=n;i++){ if(a[i]<mid){ if(mid-a[i]>b[i]) return 0; sum+=mid-a[i]; if(sum>m) return 0; } } return 1; } int main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=n;i++) scanf("%lld",&b[i]); LL l=0,r=n*2,ans=0; while(l<=r){ LL mid=(l+r)/2; if(check(mid)){ l=mid+1; ans=mid; }else{ r=mid-1; } } printf("%lld\n",ans); return 0; }

SMU Winter 2023 Round #13 (Div.2)

B题 BM算日期

这题只需注意一下,左边取较小的,右边取较大的即可。

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #include<map> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define ll long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; void solve() { int y, a, l, r; cin >> y >> a; l = min(y, y + a), r = max(y, y + a); if (y + a > 9999) { int t = y + a - 9999; r = max(y, 9999 - t); l = min(y, 9999 - t); } int cnt = 0; for (int i = l; i <= r; i++) { if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) cnt++; } cout << cnt << endl; } int main() { IOS; CC; int h_h = 1; cin >> h_h; while (h_h--) solve(); return 0; }

E题 BM充饥

签到题目

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define ll long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; void solve() { string s; cin >> s; printf(R"( __ _____ | | ___/ ____\____ | |/ /\ __\/ ___\ | < | | \ \___ |__|_ \ |__| \___ > \/ \/)"); } int main() { IOS; CC; int h_h = 1; //cin >> h_h; while (h_h--) solve(); return 0; }

H题 Hsueh- Draw Progress

按照题目模拟即可,有一个细节,要先算出小数在保留后两位,那我们的操作就是除成小数以后乘以100再强制类型转换为int即可。

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define ll long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; void solve() { int n, m; cin >> n >> m; cout << '['; for (int i = 0; i < m; i++)cout << '#'; for (int i = 0; i < n - m; i++)cout << '-'; cout << "] "; cout << (int) ((D) m / n * 100) << '%' << endl; } int main() { IOS; CC; int h_h = 1; cin >> h_h; while (h_h--) solve(); return 0; }

J题 大扫除

这题我们可以一层一层的搜,每层的垃圾用set来维护,自动去重,没遍历完一层就把它加到答案里并且清空set继续遍历下一层。

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define ll long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; void solve() { set<char> st; int n; cin >> n; int cnt=0; for (int i = 0; i < n; i++) { string s; cin >> s; for (int j = 0; j < s.size(); j++) { if (s[j] != '.') st.insert(s[j]); } //for(auto i:st)cout<<i<<' ';cout<<endl; cnt+=(int)st.size(); st.clear(); } cout << cnt << endl; } int main() { IOS; CC; int h_h = 1; cin >> h_h; while (h_h--) solve(); return 0; }

J题 旅游

数字位数过多可以用字符串来存,然后遍历字符串,最后判断结果即可。

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define ll long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; void solve() { int cnt = 0; for (int i = 0; i < 4; i++) { string s; cin >> s; int sum = 0; for (int j = 0; j < s.size(); j++) { sum += s[j] - '0'; } if(sum==6||sum>=16)cnt++; } if (cnt == 4)cout << "Oh my God!!!!!!!!!!!!!!!!!!!!!" << endl; if (cnt == 3)cout << "Bao Bao is a SupEr man///!" << endl; if (cnt == 2)cout << "BaoBao is good!!" << endl; if (cnt == 1)cout << "Oh dear!!" << endl; if (cnt == 0)cout << "Bao Bao is so Zhai......" << endl; } int main() { IOS; CC; int h_h = 1; //cin >> h_h; while (h_h--) solve(); return 0; }

D题 Palindrome Hard Problem

这题是典型的贪心,因为每个字符就可以构成回文串,所一回文串最多就是所有字符串加在一起的长度。

#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<set> #include<queue> #include<stack> #define IOS ios::sync_with_stdio(false) #define CC cin.tie(nullptr),cout.tie(nullptr) #define ll long long #define f first #define s second using namespace std; typedef pair<int ,int> PII; typedef double D; const int N = 100010, M = 1e5 + 10; void solve() { int n; cin >> n; string s; int sum=0; for (int i = 0; i < n; i++) { string s1; cin >> s1; s+=s1; } cout << s.size() << endl; } int main() { IOS; CC; int h_h = 1; //cin >> h_h; while (h_h--) solve(); return 0; }

SMU Winter 2023 Round #7 (Div.2)

A题 解开束缚缠丝Ⅱ

题意:求给出的n个字符最长可以组成多长的回文串。

思路:就是统计字符出现的次数,要么全部是偶数全部可以构成回文串,如果有奇数,那么只有其中一个奇数的字符串可以放入回文串中,用map来做就可以了。

#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--){ int n; cin>>n; map <char,int> mp; int ans=0; for(int i=0;i<n;i++){ char ch; cin>>ch; mp[ch]++; } for(auto i:mp){ if(i.second%2!=0)ans++; } //cout<<ans<<' '; cout<<n-ans+1<<endl; } return 0; }

B题 7 的意志

题意:求有最多几个区间的和为7777

思路:先进行前缀和预处理,然后枚举每一个可能的区间和的左端点,寻找可行的右端点。一个左端点最多只有一个可行的右端点进行匹配

#include<bits/stdc++.h> using namespace std; typedef long long ll; int n, ans; int a[100005], s[100005]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); ll t; cin>>t; while (t--) { cin >> n; s[0] = ans = 0; for (int i = 1; i <= n; ++i) { cin >> a[i]; s[i] = s[i - 1] + a[i]; } for (int i = 1; i <= n; ++i) { ll tar = s[i - 1] + 7777; ll x = lower_bound(s + 1, s + n + 1, tar) - s; if (s[x] == tar) ans++; } cout << ans << '\n'; } return 0; }

F题 月光奏鸣曲

题意:给你两个正方形的数字矩阵,可以逆时针和顺时针转动,问最少转几次让两个矩阵相等。

思路:肯定只能往一个方向转,不然只要有一个向另外一个方向转了,就会抵消本方向的一次,相当于没有转,但是操作次数却多了两次,题目求最少,并且做多只有可能转三次,第四次就回原位置了,写四个转零次,一次,两次,三次的函数判断一下即可。

#include<bits/stdc++.h> using namespace std; typedef long long LL; int n; int a[25][25], b[25][25]; bool check0() { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { if (b[i][j] != a[i][j]) return false; } } return true; } bool check1() { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { if (b[i][j] != a[n - j + 1][i]) return false; } } return true; } bool check2() { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { if (b[i][j] != a[j][n - i + 1]) return false; } } return true; } bool check3() { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { if (b[i][j] != a[n - i + 1][n - j + 1]) return false; } } return true; } void main2() { cin >> n; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { cin >> a[i][j]; } } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { cin >> b[i][j]; } } if (check0()) cout << 0 << '\n'; else if (check1()) cout << 1 << '\n'; else if (check2()) cout << 1 << '\n'; else if (check3()) cout << 2 << '\n'; else cout << -1 << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); LL _; cin >> _; // _ = 1; while (_--) main2(); return 0; }

H题 简单的 LRU 问题

就是根据题目所说模拟一下就可以了,但是有点复杂,要耐得住性子

#include<bits/stdc++.h> using namespace std; typedef long long LL; int n, m, mx; int a[105][10]; string hx = "0123456789abcdef"; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m; mx = 0; cout << "+------+"; for (int i = 0; i < n; ++i) { cout << "--------+"; } cout << '\n'; cout << "| |"; for (int i = 0; i < n; ++i) { cout << " 0x"; int a = i / 16, b = i % 16; cout << hx.substr(a, 1) << hx.substr(b, 1) << " |"; } cout << '\n'; cout << "+------+"; for (int i = 0; i < n; ++i) { cout << "--------+"; } cout << '\n'; for (int i = 0; i < m; ++i) { int x; cin >> x; if (i == 0) a[0][0] = x; else { int have = 0; for (int j = 0; j <= mx; ++j) { if (a[i - 1][j] == x) { have = 1; break; } } if (have) { int k = 0; for (int j = 0; j <= mx; ++j) { if (a[i - 1][j] == x) continue; a[i][k++] = a[i - 1][j]; } a[i][mx] = x; } else { if (mx < n - 1) { for (int j = 0; j <= mx; ++j) { a[i][j] = a[i - 1][j]; } a[i][++mx] = x; } else { int k = 0; for (int j = 1; j <= mx; ++j) { a[i][k++] = a[i - 1][j]; } a[i][mx] = x; } } } cout << "| 0x"; int A, B, C, D; A = i / 16; B = i % 16; cout << hx.substr(A, 1) << hx.substr(B, 1) << " |"; for (int j = 0; j <= mx; ++j) { cout << " 0x"; int tmp = a[i][j]; A = tmp / 4096; tmp -= A * 4096; B = tmp / 256; tmp -= B * 256; C = tmp / 16; tmp -= C * 16; D = tmp; cout << hx.substr(A, 1) << hx.substr(B, 1); cout << hx.substr(C, 1) << hx.substr(D, 1) << " |"; } for (int j = mx + 1; j < n; ++j) { cout << " |"; } cout << '\n'; cout << "+------+"; for (int i = 0; i < n; ++i) { cout << "--------+"; } cout << '\n'; } return 0; }

I题 好想听肆宝唱歌啊

题意:给你几首个的名字以及喜爱它的程度,数字越大喜爱程度越高,再给你个数字k,就是最爱的前k首歌曲已经点了,现在要点目前情况下最喜爱的歌曲,输出该歌曲的名字。

思路:使用一个结构体进行排序,如果输出k+1首歌曲的名字就可以了。

#include<bits/stdc++. using namespace std; typedef long long LL; const int N=100010; int n; struct S { int w; string x; }s[N]; bool cmp(S a,S b){ return a.w>b.w; } int main() { cin >> n; for (int i = 1; i <= n; i++) cin >> s[i].w >> s[i].x; sort(s + 1, s + n + 1, cmp); int k; cin >> k; cout << s[k + 1].x; return 0; }

J 题 毁灭凤凰人

#include<bits/stdc++.h> using namespace std; int n, m; int mxa = 0, a = 0, b = 0; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n >> m; for (int i = 1; i <= n; ++i) { int res, x; cin >> res; if (res == 0) { cin >> x; mxa = max(mxa, x); } else if (res == 1) a = 1; else b = 1; } if (m == 0 && mxa >= 2500 && a) { cout << "haoye\n"; return 0; } else if (m == 1 && mxa > 2100 && a) { cout << "haoye\n"; return 0; } else if (b && n > 1) { cout << "haoye\n"; return 0; } else cout << "QAQ\n"; return 0; }

K题 欢迎来到杭师大

题意:给你一个n,输出n个Welcome to HZNU,每个要换行

思路:先定义一个字符串,用个循环输出即可。

#include<bits/stdc++.h> #define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr) using namespace std; int main() { IOS; int n; cin>>n; string s="Welcome to HZNU"; while(n--){ cout<<s<<'\n'; } return 0; }

L题 Ayanoto 变形记

题意:给n个点,每次条x步,问再其中一个位置,能不能跳回原来的位置

思路:我们可以知道,总共跳的步数就是两个数的最小公倍数,但两个不为零的数肯定有最小公倍数,所以只要跳的x不为零,都可以,为零就不行。

#include<bits/stdc++.h> #define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr) #define ll long long using namespace std; int main() { IOS; ll t; cin>>t; while(t--) { ll a, b; cin >> a >> b; if (b == 0)cout << "no" << '\n'; else cout << "yes" << '\n'; } return 0; }

M题 龙学长的教诲

题意:给你一个字符串,他的顺序是1,3,5,6,4,2这样的顺序,但他正确的顺序是1,2,3,4,5,6,将正确的输出出来,标点符号在最后

思路:再读入的时候,当这个字符串的结尾有标点符号时就结束读入,将标点符号记下来,按顺序输出就可以了,记得最后加标点符号,再注意一下具体的格式。

#include<bits/stdc++.h> using namespace std; typedef long long LL; int n; string x[1005]; char op; void print(int id) { if (id != n) cout << x[id]; else { int len = x[id].length(); for (int i = 0; i < len - 1; ++i) { cout << x[id][i]; } } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin >> t; while (t--){ n=0; while (cin >> x[++n]) { int len = x[n].length(); if (x[n][len - 1] == '.' || x[n][len - 1] == '!' || x[n][len - 1] == '?') { op = x[n][len - 1]; break; } } for (int i = 1; i <= n / 2; ++i) { print(i); cout << ' '; print(n - i + 1); if (i < n / 2 or n % 2 == 1)cout << ' '; } if (n % 2 == 1) { print(n / 2 + 1); } cout << op<< '\n'; } return 0; }

哈希表

有两种方法。

拉链法
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 100003; int h[N],e[N],ne[N],idx; int n; void insert(int x){ int k=(x%N+N)%N; e[idx]=x,ne[idx]=h[k],h[k]=idx++; } bool query(int x){ int k=(x%N+N)%N; for(int i=h[k];i!=-1;i=ne[i]){ if(e[i]==x)return true; } return false; } int main() { cin>>n; memset(h,-1,sizeof h); while(n--){ char op; int x; cin>>op>>x; if(op=='I')insert(x); else { if(query(x))puts("Yes"); else puts("No"); } } return 0; }
开放寻址法
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 300007, inf=0x3f3f3f3f; int h[N]; int n; int find(int x){ int k=(x%N+N)%N; while(h[k]!=inf&&h[k]!=x){ k++; if(k==N-1)k=0; } return k; } int main() { cin>>n; memset(h, 0x3f, sizeof h); while (n -- ){ char op; int x; cin>>op>>x; if(op=='I')h[find(x)]=x; else { if(h[find(x)]!=inf)puts("Yes"); else puts("No"); } } return 0; }

字符串哈希

处理字符串问题的利器

#include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ull; const int N = 100010, P=131; ull p[N], h[N]; int n,m; char s[N]; ull getSum(int l,int r){ return h[r]-h[l-1]*p[r-l+1]; } int main() { cin>>n>>m>>s+1; p[0]=1; for(int i=1;i<=n;i++){ h[i]=h[i-1]*P+s[i]; p[i]=p[i-1]*P; } while (m -- ){ int l1,r1,l2,r2; cin>>l1>>r1>>l2>>r2; if(getSum(l1,r1)==getSum(l2,r2))puts("Yes"); else puts("No"); } return 0; }

单调栈

#include <iostream> #include <cstring> #include <algorithm> #include<stack> using namespace std; const int N = 100010; int n; int a[N]; int main() { stack<int> st; cin>>n; for(int i=0;i<n;i++)cin>>a[i]; for(int i=0;i<n;i++){ while(st.size()&&a[i]<=st.top())st.pop(); if(st.size())cout<<st.top()<<' '; else cout<<-1<<' '; st.push(a[i]); } return 0; }

单调队列

#include <iostream> #include <cstring> #include <algorithm> #include<queue> using namespace std; const int N = 1000010; int q[N]; int n, k; int a[N]; int tt=-1, hh; int main() { cin >> n >> k; for(int i = 0; i < n; i ++)cin >> a[i]; for (int i = 0; i < n; i++) { if (hh <= tt && i - k + 1 > q[hh])hh ++;; while (hh <= tt && a[q[tt]] >= a[i])tt--; q[++tt] = i; if (i+1>=k)cout << a[q[hh]] << ' ' ; } cout<<endl; tt = -1, hh = 0; for (int i = 0; i < n; i++) { if (hh <= tt && i - k + 1 > q[hh])hh ++;; while (hh <= tt && a[q[tt]] <= a[i])tt--; q[++tt] = i; if (i+1>=k)cout << a[q[hh]] << ' ' ; } return 0; }

__EOF__

本文作者north_h
本文链接https://www.cnblogs.com/north-h/p/17619570.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   north_h  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示