計蒜客上藍橋杯模擬題的部分題解
<A>
思路:按照題意暴力就行了,答案是1.
AC程式碼:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxx = 1e5 + 7; const int Inf = 1 << 30; int ans;
int main() { for(int i = 10; i < 100; i++) { int a = i % 10; //個位 int b = i / 10; //十位 int tmp = (a + b) * 3; if(tmp >= 10 && tmp < 100) { int c = tmp % 10; int d = tmp / 10; if((c + d) * 2 == i) { cout << tmp << " " << i << endl; ans++; } } } cout << ans << endl; }
<B>
思路:
用vis先把3的倍數標記,再標記5的倍數,同時取消3和5的共同倍數標記。
然後再標記7的倍數,同時標記能同時被3,5,7整除的倍數(因為同時被3,5整除的已經取消一次標記改變狀態了,所以當同時被3,5整除的數亦能夠被7整除時,再重新打上標記改變狀態)
再把只能被3,7或者只能被3,5整除的取消標記。
答案是571
AC程式碼:
#include <bits/stdc++.h> using namespace std; typedef long long ll; map <int, bool> vis; int ans;
int main() { vis.clear(); // 0表示亮著 for(int i = 1; i <= 1000; i++) { if(i % 3 == 0) vis[i] = 1; } for(int i = 1; i <= 1000; i++) { if(i % 5 == 0) { if(i % 3) vis[i] = 1; else vis[i] = 0; } } for(int i = 1; i <= 1000; i++) { if(i % 7 == 0) { if(i % 15 == 0) vis[i] = 1; else { if(i % 3 == 0) vis[i] = 0; else if(i % 5 == 0) vis[i] = 0; else vis[i] = 1; } } } for(int i = 1; i <= 1000; i++) { if(!vis[i]) ans++; } cout << ans << endl; }
<D>
思路:LIS裸板子,在程式的空缺處填寫:f[i] = max(f[i], f[j] + 1);
<A>
思路:C語言基礎題,看過我部落格的都知道,與列印圖案有關的這種題,他的解題技巧就是找到當前元素行列的角標與他這個位置的圖案的關係就行,說白了就是找規律,他這個是取矩陣各邊中點連起來形成一個新矩陣,那我就把新矩陣裡沒覆蓋到原矩陣的點對應的值都換成0就行了,那這個新矩陣的範圍就按我說的,找!規!律!答案是26020201
AC程式碼:
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n; int a[105][105]; ll sum;
int main() { int t = 0; cin >> n; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) a[i][j] = ++t; int tmp = n / 2 + 1;
for(int i = 1; i < tmp; i++) for(int j = 1; j <= tmp - i; j++) a[i][j] = 0; for(int i = tmp + 1; i <= n; i++) for(int j = 1; j <= i - tmp; j++) a[i][j] = 0; for(int i = 1; i < tmp; i++) for(int j = tmp + i; j <= n; j++) a[i][j] = 0; for(int i = tmp + 1; i <= n; i++) for(int j = n; j > n - i + tmp; j--) a[i][j] = 0;
/*for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { printf("%d ", a[i][j]); } printf("\n"); }*/
for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) sum += (ll)a[i][j]; cout << sum << endl; // n = 101 -> sum = 26020201 }
<B>
思路:先DFS處理出0~7的全排列,先把0開頭的刪了,再只留下所有以1,3,7結尾的素數,然後列舉就行了,答案是2668.
AC程式碼:
#include <bits/stdc++.h> using namespace std; const int maxx = 1e6 + 7; bool vis[10]; int ans[10]; int n; int tmp[maxx]; int t; int cnt;
void Dfs(int x) { if(x == n + 1) { int c = 1; if(ans[n] != 1 && ans[n] != 3 && ans[n] != 7) return ; if(!ans[0]) return ; ++t; for(int i = n; i >= 0; i--) { tmp[t] += ans[i] * c; c *= 10; } } for(int i = 0; i <= n; i++) { if(!vis[i]) { vis[i] = 1; ans[x] = i; Dfs(x + 1); vis[i] = 0; } } }
int main() { scanf("%d", &n); Dfs(0); //for(int i = 1; i <= t; i++) printf("%d\n", tmp[i]); for(int i = 1; i <= t; i++) { bool flg = 1; for(int j = 2; j <= sqrt(tmp[i]); j++) { if(tmp[i] % j == 0) { flg = 0; break; } } if(flg) cnt++; } cout << cnt << endl; return 0; }
<E>
思路:這題就是階乘的性質,答案處填 n/= 5
<A>
思路:直接暴力就行了,答案是45
AC程式碼:
#include <bits/stdc++.h> using namespace std; int a, b;
int main() { // ba + ab = x; // |ba - ab| = y; // x - y = 32; int n = a * 10 + b; int m = b * 10 + a; if(m >= n) { // ab = 16, ba = 61 } else { // ab = 61, ba = 16 } //y = abs(61 - 16) = 45; }
<B>
思路:這題依舊很暴力,三層迴圈跑一遍就OK了,答案是181
AC程式碼:
#include <bits/stdc++.h> using namespace std; const int Inf = 1 << 30;
int main() { // 11x + 13y + 17z = 2471 // 13x + 17y + 11z = 2739 int ans = Inf; for(int i = 1; i <= 250; i++) { for(int j = 1; j <= 250; j++) { for(int k = 1; k <= 250; k++) { if(11 * i + 13 * j + 17 * k == 2471 && 13 * i + 17 * j + 11 * k == 2739) { ans = min(ans, i + j + k); } } } } cout << ans << endl; }
<C>
思路:dfs一遍1~9的全排列,在裡面記一個滿足題意的cnt即可,就把3*3的矩陣變成1*9的全排列,注意角標對應就行,答案是72
AC程式碼:
#include <bits/stdc++.h> using namespace std;
bool vis[10]; int ans[10]; int n; int cnt = 0;
void Dfs(int x) { if(x == n + 1) { int s1 = 0, s2 = 0, s3 = 0; for(int i = 1; i <= 3; i++) s1 += ans[i]; for(int i = 4; i <= 6; i++) s2 += ans[i]; for(int i = 7; i <= 9; i++) s3 += ans[i]; if(s1 != s2 || s2 != s3 || s1 != s3) return ; s1 = 0, s2 = 0, s3 = 0; for(int i = 1; i <= n; i++) { if(i % 3 == 1) s1 += ans[i]; else if(i % 3 == 2) s2 += ans[i]; else s3 += ans[i]; } if(s1 != s2 || s2 != s3 || s1 != s3) return ; cnt++; } for(int i = 1; i <= n; i++) { if(!vis[i]) { vis[i] = 1; ans[x] = i; Dfs(x + 1); vis[i] = 0; } } }
int main() { scanf("%d", &n); Dfs(1); cout << cnt << endl; return 0; }
<D>
思路:我剛說什麼了~列印圖案~找!規!律!答案是:j == n - i - 1
AC程式碼:
#include <bits/stdc++.h> using namespace std;
void print(int n) { for(int i = 0; i < n - 1; ++i) { for(int j = 0; j <= n + i - 1; ++j) { if(/**/j == n - i - 1) printf("*"); else if(j == n + i - 1) printf("*"); else printf(" "); } printf("\n"); } for(int i = 0; i < n * 2 - 1; ++i) printf("*"); printf("\n"); }
int main() { for(int i = 1; i <= 16; i *= 2) print(i); }
<H>
思路:C++基礎題,STL中map的應用,也是一道完整的程式設計題,對於初學者來說,是一道不錯的題呦~~~
宣告一個<string, bool>型的map,名為vis,insert一個串,我就打上標記,即當前 vis 為1,那我在find的時候,如果vis = 0,那我就列印-1。找得到,我用max維護一下最大值就OK了~
AC程式碼:
#include <bits/stdc++.h> using namespace std; string s; string t[1007]; int a[1007]; map <string, bool> vis; string x;
int main() { int p = 0; vis.clear(); while(cin >> s && s != "end") { if(s[0] == 'i') { cin >> t[++p]; cin >> a[p]; vis[t[p]] = 1; } else if(s[0] == 'f') { cin >> x; if(!vis[x]) puts("-1"); else { int ans = 0; for(int i = 1; i <= p; i++) { if(t[i] == x) ans = max(ans, a[i]); } cout << ans << endl; } } } }