#include<bits/stdc++.h>
using namespace std;typedeflonglong LL;typedef pair<int,int> PII;constint N =1010, INF =0x3f3f3f3f;int n, a[N];
PII b[N];
bool st[N];intcal(int t1,int t2){int ret =0;while(2* t1 < t2){ret ++;t1 *=2;}return ret;}intmain(){int t; cin >> t;while(t --){cin >> n;LL x =0;for(int i =1; i <= n; i ++){scanf("%d",&a[i]);}double cnt;for(int i =1, t1, t2; i < n; i ++){t1 =min(a[i], a[i +1]), t2 =max(a[i], a[i +1]);if(t1 *2>= t2)continue;else{x +=cal(t1, t2);}}cout << x << endl;}return0;}
直接上公式,沒(méi)有過(guò),應(yīng)該是小數(shù)精度會(huì)被卡
#include<bits/stdc++.h>
using namespace std;typedeflonglong LL;typedef pair<int,int> PII;constint N =1010, INF =0x3f3f3f3f;int n, a[N];intmain(){int t; cin >> t;while(t --){cin >> n;LL x =0;for(int i =1; i <= n; i ++){scanf("%d",&a[i]);}double cnt;for(int i =1, t1, t2; i < n; i ++){t1 =min(a[i], a[i +1]), t2 =max(a[i], a[i +1]);if(t1 *2>= t2)continue;else{x +=ceil(log(t2 *1.0/ t1)/log(2))-1;}}cout << x << endl;}return0;}
#include<bits/stdc++.h>
using namespace std;typedeflonglong LL;constint N =100010;
LL n;
LL a[N];
map<LL, bool> m;intmain(){int t; cin >> t;for(LL i =1; i <=10010; i ++)// 這里僅僅寫(xiě)到 10000就會(huì) WA,主要是怕他多往后走了一步,查詢到了0{a[i]= i * i * i;m[a[i]]= true;}// cout << m[0] << endl;while(t --){scanf("%lld",&n);bool flag = false;LL surp;for(int i =1;!flag && a[i]<= n; i ++){surp = n - a[i];if(m[surp]== true){flag = true;}}if(flag)puts("YES");elseputs("NO");}return0;}
D. Permutation Transformation
http://codeforces.com/contest/1490/problem/D
一個(gè)簡(jiǎn)單的模擬dfs,每次在區(qū)間找最大值作為 root 即可
#include<bits/stdc++.h>
using namespace std;constint N =110;int a[N], n, depth[N];voidbuild(int fa,int l,int r){if(l >= r)return;int u =-1, v =-1;// 左子樹(shù)for(int i = l; i < fa; i ++){if(u ==-1|| a[u]< a[i])u = i;}depth[u]= depth[fa]+1;build(u, l, fa -1);// 右子樹(shù)for(int i = fa +1; i <= r; i ++){if(v ==-1|| a[v]< a[i])v = i;}depth[v]= depth[fa]+1;build(v, fa +1, r);}intmain(){int t; cin >> t;while(t --){scanf("%d",&n);for(int i =1; i <= n; i ++)scanf("%d",&a[i]);memset(depth,-1,sizeof depth);int v;for(int i =1; i <= n; i ++){if(a[i]== n){v = i;break;}}depth[v]=0;build(v,1, n);cout << depth[1];for(int i =2; i <= n; i ++)printf(" %d", depth[i]);cout << endl;}return0;}
#include<bits/stdc++.h>
using namespace std;typedeflonglong LL;typedef pair<LL,int> PII;constint N =200010;
vector<int> res;
LL a[N];
LL b[N];
PII c[N];int n;bool cmp(const PII &t1,const PII &t2){return t1.first < t2.first;}intmain(){int t; cin >> t;while(t --){scanf("%d",&n);for(int i =1; i <= n; i ++){scanf("%lld",&a[i]);c[i].first = a[i];c[i].second = i;}sort(c +1, c + n +1, cmp);for(int i =1; i <= n; i ++)b[i]= b[i -1]+ c[i].first;res.clear();res.push_back(c[n].second);for(int i = n -1; i >=1; i --){if(b[i]>= c[i +1].first)res.push_back(c[i].second);elsebreak;}sort(res.begin(), res.end());cout << res.size()<< endl;cout << res[0];for(int i =1; i < res.size(); i ++)printf(" %d", res[i]);cout << endl;}return0;}
#include<bits/stdc++.h>
using namespace std;typedef pair<int,int> PII;typedeflonglong LL;constint INF =0x3f3f3f3f;constint N =200010;int a[N +5];int n;
map<int,int> m;int cnt[N +5];int sum[N +5];
LL addval[N +5];intmain(){int t; cin >> t;while(t --){m.clear();scanf("%d",&n);for(int i =1; i <= n; i ++){scanf("%lld",&a[i]);m[a[i]]++;}memset(cnt,0,sizeof cnt);memset(sum,0,sizeof sum);memset(addval,0,sizeof addval);map<int,int>::iterator it;for(it = m.begin(); it != m.end(); it ++)// 出現(xiàn)it->second 次數(shù)的數(shù)字進(jìn)行統(tǒng)計(jì){/// printf("IT: %d, %d\n", it->first, it->second);cnt[it->second]++;}// 計(jì)算前綴數(shù)組和累加和數(shù)組for(int i =1; i <= n; i ++)// 最多出現(xiàn) n 次{sum[i]= sum[i -1]+ cnt[i];addval[i]= addval[i -1]+LL(cnt[i])* i;}/*printf("CNT:\n\t");for (int i = 1; i <= n; i ++ ){printf("%d ", cnt[i]);}cout << endl;
*/LL res =1e16;LL up, down;for(int i =1; i <= n; i ++){down = addval[i -1];up =(addval[n]- addval[i -1])-(sum[n]- sum[i -1])* i;res =min(res, up + down);}cout << res << endl;}return0;}
G. Old Floppy Drive
http://codeforces.com/contest/1490/problem/G
本題是一個(gè)較為隱蔽的二分題目,需要我們貪心預(yù)處理出來(lái)可以二分的數(shù)組。 首先我們先將前綴數(shù)組給求出來(lái), 并且貪心得到 cnt不斷增加,而且前綴和也增加的數(shù)字,將其放入數(shù)組v, 具體見(jiàn)代碼max_val部分。 那么數(shù)組 v 是一個(gè)數(shù)值(無(wú)論是val,還是opt_cnt)都不斷增加的數(shù)據(jù)
倘若 xix_ixi?在 數(shù)組 v 最大值的范圍之內(nèi),那么直接二分找最小的cnt
否則,需要判斷一下整個(gè)原數(shù)組 a 的累加和是否大于零,倘若小于等于0,無(wú)解
否則,是可以經(jīng)過(guò)不斷的循環(huán)找到這個(gè)數(shù)的,首先我們根據(jù)max(v)找到最小的循環(huán)次數(shù),然后二分即可。 本題最坑的點(diǎn)就是 long long 開(kāi)的地方很多,幾乎所有的數(shù)據(jù)都要開(kāi)long long
#include<bits/stdc++.h>
using namespace std;typedeflonglong LL;const LL INF =0x3f3f3f3f3f3f3f3f;constint N =200010;int n, m;
LL a[N], x[N];
LL sum[N];
class Node
{
public:LL val, cnt;Node(LL _val =0, LL _cnt =0){val = _val, cnt = _cnt;}}b[N];intmain(){int t; cin >> t;while(t --){cin >> n >> m;LL cur_max =-INF;b[1]=Node(-INF,-1);int n2 =1;sum[0]=0LL;for(int i =1; i <= n; i ++){scanf("%lld",&a[i]);sum[i]= sum[i -1]+ a[i];if(sum[i]> cur_max){cur_max = sum[i];b[++ n2]=Node(cur_max, i -1);// 注意在這里的 - 1}}for(int i =1; i <= m; i ++)scanf("%lld",&x[i]);// 當(dāng)前的 b 數(shù)字 是 1~n val 增加, cnt增加的遞增數(shù)組,下面我們的 x 僅僅只需要二分即可;/// printf("RES:\n\t");LL loop = sum[n];for(int i =1; i <= m; i ++){if(b[n2].val >= x[i])// 可以直接二分找 >= x[i] 的最小值{int l =1, r = n2, mid;while(l < r){mid = l + r >>1;if(b[mid].val >= x[i])r = mid;elsel = mid +1;}printf("%lld ", b[l].cnt);}else// 查看他的 loop{if(loop <=0)// 無(wú)法達(dá)到{printf("-1 ");}else{LL loopcnt =(x[i]- b[n2].val)/ loop +((x[i]- b[n2].val)% loop !=0);x[i]-= loopcnt * loop;int l =1, r = n2, mid;while(l < r){mid = l + r >>1;if(b[mid].val >= x[i])r = mid;elsel = mid +1;}printf("%lld ", b[l].cnt + loopcnt * n);// loopcnt 是乘以 n 的}}}puts("");}return0;}創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)