日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

第十二届蓝桥杯C++赛后感

發布時間:2023/12/3 c/c++ 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第十二届蓝桥杯C++赛后感 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • A 空間
  • 卡片
  • 直線
  • 貨物擺放
  • 路徑
  • 時間顯示
  • G砝碼稱重
  • H楊輝三角形
  • 雙向排列
  • J括號序列

注:有些代碼忘了考試時怎么寫的了,(我也懶得重新寫),所以很多題的代碼是acwing藍橋杯講解里的,我對其進行注釋和修改

A 空間


32位程序中,INT變量占用4個字節
1mb=1024kb
1kb=1024B
1B=8b
B:byte
b:bit
32位二進制數是四個字節
實際上就是求256MB有多少個32 bit

答案:256*1024*1024/4 = 67108864

卡片


直接模擬即可

#include<bits/stdc++.h> #define debug(a,b) printf("%s = %d\n",a,b) typedef long long ll; using namespace std;inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w; } int a[10];bool iff(int x) {while (x) {int y = x % 10;if (a[y])a[y]--;elsereturn 0;x /= 10;}return 1; }int main() {for (int i = 0; i <= 9; i++) a[i] = 2021;for (int i = 1;; i++) {if (!iff(i)) {cout << i - 1 << endl;break;}}return 0; } 答案:3181

直線


比賽時用set實現的,忘了自己做的對不對。。
我當時做的方法是因為兩點確定一線,所以枚舉兩個點,然后用set記錄斜率和截距(y=k*x+b),但是k有可能不存在,所以最后的答案還要額外加上20
當時代碼懶得寫了,按照其他博主的寫法重新寫的,只不過用的不是set,存下所有k和b后,排序,將重復的k和b刪掉

#include<bits/stdc++.h> #define debug(a,b) printf("%s = %d\n",a,b) typedef long long ll; using namespace std;inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w; } const int maxn = 200000; double eps=1e-8; int n; struct Line {double k, b;bool operator< (const Line& t) const{if (k != t.k) return k < t.k;return b < t.b;} }L[maxn];int main() {for (int x1 = 0; x1 < 20; x1 ++ )for (int y1 = 0; y1 < 21; y1 ++ )for (int x2 = 0; x2 < 20; x2 ++ )for (int y2 = 0; y2 < 21; y2 ++ )if (x1 != x2){double k = (double)(y2 - y1) / (x2 - x1);double b = y1 - k * x1;L[n ++ ] = {k, b};//存兩點所形成的直線 }sort(L, L +maxn);int res = 1;for (int i = 1; i < n; i ++ )if (fabs(L[i].k - L[i - 1].k) > eps || fabs(L[i].b - L[i - 1].b) > eps)//說明不是一條直線 res ++ ;cout << res + 20 << endl;//加20是因為k不存在的直線也要考慮 return 0; }

我當時的做法是對的,但是最后的答案忘了是不是這個

答案:40257

貨物擺放


LWH都是n的約數,問有多少種方案,其實就是求n的約數,用這些約數進行組合。因為約數不是很多,所以三重循環枚舉約數,看是否等于n
對n求約束,直接開方求就行(因為如果x是約數,那么n/x也是,所以只需要將范圍縮小到根號n)
(比賽時我是這么做的,確信)

#include <iostream> #include <cstring> #include <algorithm> #include <vector>using namespace std;typedef long long LL;int main() {LL n;cin >> n;vector<LL> d;for (LL i = 1; i * i <= n; i ++ )if (n % i == 0){d.push_back(i);if (n / i != i) d.push_back(n / i);}int res = 0;for (auto a: d)for (auto b: d)for (auto c: d)if (a * b * c == n)res ++ ;cout << res << endl;return 0; } 答案:2430

路徑


就是一個建邊跑最短路。。比賽時忘了gcd咋寫emm
好像有的用dp來做?

#include <iostream> #include <cstring> #include <algorithm>using namespace std;const int N = 2200, M = N * 50;int n; int h[N], e[M], w[M], ne[M], idx; int q[N], dist[N]; bool st[N];int gcd(int a, int b) // 歐幾里得算法 {return b ? gcd(b, a % b) : a; }void add(int a, int b, int c) // 添加一條邊a->b,邊權為c {e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ; }void spfa() // 求1號點到n號點的最短路距離 {int hh = 0, tt = 0;memset(dist, 0x3f, sizeof dist);dist[1] = 0;q[tt ++ ] = 1;st[1] = true;while (hh != tt){int t = q[hh ++ ];if (hh == N) hh = 0;st[t] = false;for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (dist[j] > dist[t] + w[i]){dist[j] = dist[t] + w[i];if (!st[j]) // 如果隊列中已存在j,則不需要將j重復插入{q[tt ++ ] = j;if (tt == N) tt = 0;st[j] = true;}}}} }int main() {n = 2021;memset(h, -1, sizeof h);for (int i = 1; i <= n; i ++ )for (int j = max(1, i - 21); j <= min(n, i + 21); j ++ ){int d = gcd(i, j);add(i, j, i * j / d);}spfa();printf("%d\n", dist[n]);return 0; } 答案:10266837

時間顯示


比賽時忘了1s等于多少ms,還好電腦自帶計算器里有時間的進制關系(狗頭🐕)

#include <iostream> #include <cstring> #include <algorithm>using namespace std;typedef long long LL;int main() {LL n;cin >> n;n /= 1000;n %= 86400;int h = n / 3600;n %= 3600;int m = n / 60;int s = n % 60;printf("%02d:%02d:%02d\n", h, m, s);return 0; }

G砝碼稱重


背包問題
自己對dp真的不熟。。五一要好好練練dp

對于每個砝碼他有三個選擇,稱的左側,右側和不放,
我們設dp[i][j]表示前i個物品中,總質量為j的情況是否存在,dp為bool型
對于第j個物品,我們說了有三種選擇,所以我們可以得到轉移方程:

分別對應不選,放左側,放右側 dp[i][j]|=dp[i-1][j] dp[i][j]|=dp[i-1][j-w[i]] dp[i][j]|=dp[i-1][j+w[i]]

按照題目要求j-w[i]最小為-m,數組不能用負下標,所以我們加一個偏移量B,保證數組下標都為非負

#include <iostream> #include <cstring> #include <algorithm>using namespace std;const int N = 110, M = 200010, B = M / 2;int n, m; int w[N]; bool f[N][M];int main() {scanf("%d", &n);for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]), m += w[i];f[0][B] = true;for (int i = 1; i <= n; i ++ )for (int j = -m; j <= m; j ++ ){f[i][j + B] = f[i - 1][j + B];if (j - w[i] >= -m) f[i][j + B] |= f[i - 1][j - w[i] + B];if (j + w[i] <= m) f[i][j + B] |= f[i - 1][j + w[i] + B];}int res = 0;for (int j = 1; j <= m; j ++ )if (f[n][j + B])res ++ ;printf("%d\n", res);return 0; }

H楊輝三角形



因為楊輝三角形左右對稱,所以我們只考慮左半部分
我們進行枚舉可以看出,斜列的數量不會超過20個,所以枚舉每一個斜列,每個斜列的第一個元素也是遞增排列且有關系(第一個斜列的首元素為C(1,0),第二個為C(1,2),第三個為C(2,4),…C(x,2x)),斜列內的元素是遞增排列的,且大小都有公式關系(比如第3個斜列,第一個元素是C(2,4),第二個元素是C(2,5),然后是C(2,6)…),然后二分找具體位置
如果第C(r,k)是我們要找的元素,他的位置就是r * (r + 1) / 2 + k + 1
思維題
妙啊,當時寫了一個半暴力,真想不到

#include <iostream> #include <cstring> #include <algorithm>using namespace std;typedef long long LL;int n;LL C(int a, int b) {LL res = 1;for (int i = a, j = 1; j <= b; i --, j ++ ){res = res * i / j;if (res > n) return res;}return res; }bool check(int k) {//C(a,b)//a>=2b,二分a LL l = k * 2, r = n;while (l < r){LL mid = l + r >> 1;if (C(mid, k) >= n) r = mid;else l = mid + 1;}if (C(r, k) != n) return false;cout << r * (r + 1) / 2 + k + 1 << endl;return true; }int main() {cin >> n;for (int k = 16; ; k -- )if (check(k))break;return 0; }

雙向排列

講解鏈接

J括號序列


肯定是dp,但是我不會。。。等會了再更新

總結

以上是生活随笔為你收集整理的第十二届蓝桥杯C++赛后感的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。