浙江省程式設計競賽2019
阿新 • • 發佈:2020-09-19
B - Element Swapping
題意:
題解
可以求得a[i] + a[j] = d2/d1
#include <iostream> #include <string> #include <cstdlib> #include <algorithm> #include <cmath> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <assert.h> #includeView Code<map> #include <set> #include <bitset> #include <iomanip> #include <stack> #include <deque> #include <unordered_map> #include <cmath> using namespace std; #define STDIN \ freopen("in.txt", "r", stdin); \ freopen("out.txt", "w", stdout); #define int long long inline int read(){char tempt = getchar();int x = 0, f = 0;while (tempt < '0' || tempt > '9')f |= tempt == '-', tempt = getchar();while (tempt >= '0' && tempt <= '9')x = x * 10 + tempt - '0', tempt = getchar();return f ? -x : x;} int n, x, y; const intN = 1e5 + 10; int a[N]; int num[N]; vector<int> get_divisors(int x) { vector<int> res; for (int i = 1; i <= min(x / i, n); i ++ ) if (x % i == 0) { res.push_back(i); if (i != x / i &&((x/i)<=n)) res.push_back(x / i); } sort(res.begin(), res.end()); return res; } signed main() { //STDIN int t; cin >> t; for (int _ = 1; _ <= t; _++) { n = read(), x = read(), y = read(); memset(num, 0, sizeof num); for (int i = 0; i < n; i++) { // scanf("%lld", &a[i]); a[i] = read(); num[a[i]]++; } int sum1 = 0; int sum2 = 0; for (int i = 0; i < n; i++) { sum1 += (i+1)*a[i]; } for (int i = 0; i < n; i++) { sum2 += (i+1)*a[i]*a[i]; } int d1 = sum1-x; int d2 = sum2-y; // cout << d1 << " " << d2 << endl; if (d1 == 0 && d2 == 0) { int cnt = 0; map<int,int> ma; for (int i = 0; i< n; i++) { if (ma.count(a[i]) >= 1) cnt += ma[a[i]]; ma[a[i]]++; } cout << cnt << endl; continue; } if (d1 == 0 || d2 == 0) { cout << 0 << endl; continue; } if (d2%d1!=0){ cout << 0 << endl; continue; } int xx = d2/d1; // cout << xx << endl; if (xx <= 0) { cout << 0 << endl; continue; } map<int, set<int> > ma; int ans = 0; vector<int> tmp = get_divisors(d1); for (int i = 0; i < n; i++) { // int d = xx-a[i]; // if (a[i] == d) continue; // if (ma.count(d) >=1 && d1%(a[i] - d) == 0 &&(d2%(a[i]*a[i]-d*d) == 0)) // { // // d1%(i-j) // auto &se = ma[d]; // for (auto &p:tmp) // { // // if (i-p > i-1) // if (p >= i) break; // if (se.find(i-p) != se.end() && (d2%p == 0)) ans++; // } // } // ma[a[i]].insert(i); int aj = xx - a[i]; int s = aj - a[i]; if (s!= 0 && aj > 0 && d1%s == 0) { int cnt = (d1)/s; cnt += i; if (cnt <= n && cnt > i && a[cnt] ==aj) ans++; } } printf("%lld\n", ans); } // cout <<get_divisors(100000).size() <<endl; }
題意:
一個數列,每次操作可以將任意一個數提至數列最前端,問至少操作幾次可以將數列變為非降數列?
題解:
可以觀察到,任何數列,都可以通過最多n-1次操作變成非降數列,我們在建一個與原來陣列一樣的陣列,從後往前考慮,如果這個數的位置正確,則跳過,如果不正確,那麼這個數肯定要往前提至少一次,那麼對於這個數前面的數,他們都會往後移一個
我們定義一個變數記錄移動次數,cnt,那麼當我們處理下一個數時,他的位置已經往後移了cnt個,那麼讓他與a[i+cnt]比較,如果相等,則跳過,如果不相等,說明在這個數之前操作的數,需要在往前移,那麼cnt++。這樣處理完cnt就是最後的答案。
const int N = 1e5 + 10; int num[N]; signed main() { // STDIN int t; cin >> t; for (int _ = 1; _ <= t; _++) { int n; cin >> n; vector<int> a(n), b(n); for (int i = 0; i < n; i++) { scanf("%d",&a[i]); b[i] = a[i]; } sort(a.begin(), a.end()); int cnt = 0; for (int i = n-1; i>= 0; i--) { if (a[(i+cnt)] != b[i]) { cnt++; } } cout <<cnt << endl; } }
F - Abbreviation
題意:
將字串的母音字母刪掉,注意第一個字母不刪,輸出處理後的字母
題解:水題
G - Lucky 7 in the Pocket
水題
H - Singing Everywhere
題意:
一個數列,如果a[i]>a[i-1] && a[i]>a[i+1],這樣算一次破音,問當最多可以刪掉一個數時,讓破音數最少,最少的破音數是多少?
題解
暴力判斷刪掉每一個數刪掉後的破音數,注意邊界的處理
#define int long long set<int> se; signed main() { //STDIN int t; cin >> t; for (int _ = 1; _ <= t; _++) { int n; cin >> n; vector<int> a; for (int i = 1; i <= n; i++) { int x; scanf("%lld", &x); a.push_back(x); } for (int i = 1; i < n-1; i++) { if (a[i] > a[i-1] && a[i] > a[i+1]) se.insert(i); } int ans = se.size(); int res = ans; for (int i = 0; i < n; i++) { if (i == 0) { if (se.find(1) != se.end()) { res = min(ans-1, res); } } else if (i == n-1) { if (se.find(n-2) != se.end()) { res = min(ans-1, res); } } else{ int t = ans; if (se.find(i) != se.end()) t--; if ( i-2 >=0) { if ( a[i-1] > a[i-2] && a[i-1] > a[i+1]) { if (se.find(i-1) == se.end()) t++; } else { if (se.find(i-1) != se.end()) t--; } } if (i+2 <= n-1 ) { if(a[i+1] > a[i-1] && a[i+1] > a[i+2]) { if (se.find(i+1) == se.end()) t++; } else{ if (se.find(i+1) != se.end()) t--; } } res = min(t, res); } } cout << res << endl; se.clear(); } }
I - Fibonacci in the Pocket
題意:
求斐波那契數列的區間和是奇數還是偶數
題解:
找規律
int mod1(string a, int b) //高精度a除以單精度b { int d = 0ll; for (int i = 0; i < a.size(); i++) d = (d * 10 + (a[i] - '0')) % b; //求出餘數 return d; } signed main() { // STDIN int t; cin >> t; for (int _ = 1; _ <= t; _++) { string a, b; cin >> a >> b; int a1 = mod1(a,3); int b1 = mod1(b,3); if ((a1 == 1 && b1 == 2) ||(a1 == 0 && b1 == 0)||(a1 == 1 &&b1 == 0)|| (a1 == 2 && b1 == 1) ||(a1 == 0 && b1 == 2)) { cout<< 0 << endl; } else cout << 1 << endl; } }