【AtCoder】diverta 2019 Programming Contest 2
diverta 2019 Programming Contest 2
A - Ball Distribution
特判一下一個人的,否則是\(N - (K - 1) - 1\)
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f; } template<class T> void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10); } int N,K; void Solve() {read(N);read(K);if(K == 1) puts("0");else {out((N - (K - 1)) - 1);enter;} } int main(){ #ifdef ivorysifreopen("f1.in","r",stdin); #endifSolve(); }B - Picking Up
枚舉p,q(就是枚舉一個點對計算p和q),判哪一種情況最優即可
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f; } template<class T> void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10); } int N; map<pii,int> zz; pii poi[55]; void Solve() {read(N);int x,y;for(int i = 1 ; i <= N ; ++i) {read(poi[i].fi);read(poi[i].se);zz[poi[i]] = 1;}int ans = N;for(int i = 1 ; i <= N ; ++i) {for(int j = 1 ; j <= N ; ++j) {if(i == j) continue;int p = poi[i].fi - poi[j].fi,q = poi[i].se - poi[j].se;int tmp = N;for(int h = 1 ; h <= N ; ++h) {tmp -= zz[mp(poi[h].fi - p,poi[h].se - q)];}ans = min(ans,tmp);}}out(ans);enter;} int main(){ #ifdef ivorysifreopen("f1.in","r",stdin); #endifSolve(); }C - Successive Subtraction
又有負數又有正數
先挑出一個正數一個負數,用這個負數減遍所有正數(除了挑出來的),再用這個正數減遍所有負數(包括挑出來的)
就可以獲得所有數的絕對值和
只有正數
會犧牲一個最小的正數,方法是挑出最小的正數,再挑一個正數,用最小的正數減遍所有的正數(除了挑出來的),再用挑的正數減掉最小的正數當前的值
只有負數
會犧牲一個最小的負數,用這個負數減遍其余負數即可
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f; } template<class T> void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10); } int N,a[100005],cnt[2]; vector<pii > ans; int64 res = 0; void Solve() {read(N);for(int i = 1 ; i <= N ; ++i) {read(a[i]);if(a[i] < 0) cnt[0]++;else cnt[1]++;}if(cnt[0] && cnt[1]) {int s,t;for(int i = 1 ; i <= N ; ++i) res += abs(a[i]);for(int i = 1 ; i <= N ; ++i) {if(a[i] >= 0) s = i;if(a[i] < 0) t = i;}for(int i = 1 ; i <= N ; ++i) {if(a[i] >= 0 && i != s) {ans.pb(mp(a[t],a[i]));a[t] -= a[i];}}for(int i = 1 ; i <= N ; ++i) {if(a[i] < 0) {ans.pb(mp(a[s],a[i]));a[s] -= a[i];}}}else if(cnt[0]) {int p = 1;for(int i = 2 ; i <= N ; ++i) {if(a[i] > a[p]) p = i;}res += a[p];for(int i = 1 ; i <= N ; ++i) {if(i != p) res += abs(a[i]);}for(int i = 1 ; i <= N ; ++i) {if(i != p) {ans.pb(mp(a[p],a[i]));a[p] -= a[i];}}}else {int p = 1,q;for(int i = 2 ; i <= N ; ++i) {if(a[i] < a[p]) p = i;}res -= a[p];for(int i = 1 ; i <= N ; ++i) {if(i != p) res += a[i];}if(p == 1) q = 2;else q = 1;for(int i = 1 ; i <= N ; ++i) {if(i != p && i != q) {ans.pb(mp(a[p],a[i]));a[p] -= a[i];}}ans.pb(mp(a[q],a[p]));}out(res);enter;for(auto t : ans) {out(t.fi);space;out(t.se);enter;} } int main(){ #ifdef ivorysifreopen("f1.in","r",stdin); #endifSolve(); }D - Squirrel Merchant
設\(f[i]\)表示有\(i\)個松果最多可以換成幾個,用金銀銅做背包就好了
不過這個背包大小最多可以是2500000……
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f; } template<class T> void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10); } int64 f[25000005],N; int g[5][5]; void Solve() {read(N);for(int i = 0 ; i < 2 ; ++i) {for(int j = 0 ; j < 3 ; ++j) {read(g[i][j]);}}for(int i = 1 ; i <= N ; ++i) f[i] = i;for(int i = 0 ; i < 3 ; ++i) {for(int s = g[0][i] ; s <= N ; ++s) {f[s] = max(f[s],f[s - g[0][i]] + g[1][i]);}}int all = f[N];for(int i = 1 ; i <= all ; ++i) f[i] = i;for(int i = 0 ; i < 3 ; ++i) {for(int s = g[1][i] ; s <= all ; ++s) {f[s] = max(f[s],f[s - g[1][i]] + g[0][i]);}}out(f[all]);enter; } int main(){ #ifdef ivorysifreopen("f1.in","r",stdin); #endifSolve(); }E - Balanced Piles
計數水平不行……
這個就是,從\(0,N\)表示最大值是0,有\(N\)個數
并且我們認為相同的值選擇順序被我們確定了
如果\(D = 1\)
那么從\(x,y\),轉移\(x + 1,0\)的時候,系數為1
從\(x,y\)轉移到\(x,y + 1\)的時候,系數為\(y + 1\),因為我們要計數這個特定的選擇順序,在\(y\)個數的排列里插上一個數,要乘上\(y + 1\)
顯然我們開頭的部分需要一個\(N!\),但是由于\(H\)的\(N!\)不必要但是被算了,所以需要\(\frac{1}{N!}\),那么兩個抵消了,所以可以直接這樣計數
我們把轉移畫成一張圖,發現每層轉移到下一層的方案數是
\((1! + 2! +3!+4!....N!)\)
然后有\(H\)層,那么方案數是(第一層的方案是1)
\((1! + 2!+3!+4!+5!....N!)^{H - 1}N!\)
那么回到原來的問題,如果我們最大值交替一共過了\(K\)個,那么方案數是
\((1! + 2!+3!+4!+5!....N!)^{K - 1}N!\)
所以我們只要做一個路徑計數,每走一步乘一個\(1! + 2!+3!+4!+5!....N!\),最后乘上一個\(\frac{N}{1!+2!+3!+4!...N!}\)
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f; } template<class T> void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10); } const int MOD = 1000000007; int N,H,D; int fac[1000005],dp[1000006],sum[1000006]; int inc(int a,int b) {return a + b >= MOD ? a + b - MOD : a + b; } int mul(int a,int b) {return 1LL * a * b % MOD; } void update(int &x,int y) {x = inc(x,y); } int fpow(int x,int c) {int res = 1,t = x;while(c) {if(c & 1) res = mul(res,t);t = mul(t,t);c >>= 1;}return res; } void Solve() {read(N);read(H);read(D);fac[0] = 1;int c = 0;for(int i = 1 ; i <= N ; ++i) {fac[i] = mul(fac[i - 1],i);update(c,fac[i]);}dp[0] = c;sum[0] = 1;for(int i = 1 ; i <= H ; ++i) {int t = sum[i - 1];if(i - D > 0) update(t,MOD - sum[i - D - 1]);dp[i] = mul(t,c);sum[i] = inc(sum[i - 1],dp[i]);}int ans = mul(dp[H],fac[N]);ans = mul(ans,fpow(c,MOD - 2));out(ans);enter; } int main(){ #ifdef ivorysifreopen("f1.in","r",stdin); #endifSolve(); }F - Diverta City
水平不行,想不到
還是類似數學歸納法那么構造,假如構造了\(i\)個點的完全圖使得所有哈密頓路徑不同,我們找到哈密頓路徑最大的那個是\(M\)
然后選擇一個數列
1,2,4,7,12,20,29,38,53,73
設\(M\)為i個點中最長哈密頓路徑最大的那個
新加一個點\(i +1\)的時候向\(j\)連一條長度為\((M + 1)a_{j}\)的邊
這個數列任意兩個數相加的值不同,且不等于其中任意一個數
這樣每條路徑經過了兩條或一條這樣的邊,剩余的部分的邊權不足以使得兩個不同的\((M + 1)k\)相等
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f; } template<class T> void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10); }int N,tot; int64 w[15][15],M,a[] = {0,1,2,4,7,12,20,29,38,53,73}; bool vis[15]; void dfs(int dep,int pre,int64 sum) {if(dep > tot) {M = max(M,sum);return;}for(int i = 1 ; i <= tot ; ++i) {if(!vis[i]) {vis[i] = 1;dfs(dep + 1,i,sum + w[pre][i]);vis[i] = 0;}} } void Solve() {read(N);M = 0;for(int i = 2 ; i <= N ; ++i) {for(int j = 1 ; j < i ; ++j) {w[i][j] = w[j][i] = (M + 1) * a[j];}tot = i;dfs(1,0,0);}for(int i = 1 ; i <= N ; ++i) {for(int j = 1 ; j <= N ; ++j) {out(w[i][j]);space;}enter;} } int main(){ #ifdef ivorysifreopen("f1.in","r",stdin); #endifSolve(); }轉載于:https://www.cnblogs.com/ivorysi/p/11068533.html
總結
以上是生活随笔為你收集整理的【AtCoder】diverta 2019 Programming Contest 2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PostgreSQL 数据库备份
- 下一篇: 你还笃信亲身经历的事情吗?来看看大脑如何