【AtCoder】CODE FESTIVAL 2017 qual B
阿新 • • 發佈:2019-02-07
date cpp b- 但是 sca dfs utc scanf ||
最近不知道為啥被安利了饑荒,但是不能再玩物喪誌了,不能頹了
饑荒真好玩
A - XXFESTIVAL
CCFESTIVAL
#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 MAXN 200005 #define eps 1e-10 //#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); } char s[55]; int L; void Solve() { scanf("%s",s + 1); L = strlen(s + 1); for(int i = 1 ; i <= L - 8 ; ++i) { putchar(s[i]); } enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
B - Problem Set
當然是選擇出毒瘤題了
#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 MAXN 200005 #define eps 1e-10 //#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,M; map<int,int> zz; void Solve() { read(N);int a; for(int i = 1 ; i <= N ; ++i) { read(a);zz[a]++; } read(M); for(int i = 1 ; i <= M ; ++i) { read(a); if(zz[a]) { zz[a]--; } else {puts("NO");return;} } puts("YES"); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
C - 3 Steps
如果圖是二分圖,那麽可以補的邊是把點黑白染色後,所有黑點都可以跟白點連邊
如果不是二分圖,因為一個奇環,那麽任意兩點之間都可以連邊,用最後圖的邊數減去原來的邊數即可
#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 MAXN 200005 #define eps 1e-10 //#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); } struct node { int to,next; }E[MAXN]; int deg[MAXN],head[MAXN],sumE,N,M; int cnt[2],col[MAXN]; void add(int u,int v) { E[++sumE].to = v; E[sumE].next = head[u]; head[u] = sumE; } bool dfs(int u) { if(col[u] == -1) col[u] = 0; ++cnt[col[u]]; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(col[v] == -1) { col[v] = col[u] ^ 1; if(!dfs(v)) return false; } else if(col[v] == col[u]) return false; } return true; } void Solve() { read(N);read(M); int a,b; for(int i = 1 ; i <= M ; ++i) { read(a);read(b); deg[a]++;deg[b]++; add(a,b);add(b,a); } memset(col,-1,sizeof(col)); if(!dfs(1)) { out(1LL * N * (N - 1) / 2 - M);enter; } else { int64 ans = 0; for(int i = 1 ; i <= N ; ++i) { if(col[i]) ans += cnt[col[i] ^ 1] - deg[i]; } out(ans);enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
D - 101 to 010
可以用一個dp實現
劃分1011111111(k個1)或11111111101(k個1),價值都是k - 1
如果這個位置連著的連續的1超過1個,最多就一種劃分
如果這個位置連著的一個1,那麽可以更新01的0前面一段的1
每個位置最多換兩次,復雜度\(O(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 MAXN 500005
#define eps 1e-10
//#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,dp[MAXN],pre[MAXN];
char s[MAXN];
void Solve() {
read(N);
scanf("%s",s + 1);
for(int i = 1 ; i <= N ; ++i) {
if(s[i] == ‘0‘) pre[i] = i;
else pre[i] = pre[i - 1];
}
for(int i = 1 ; i <= N ; ++i) {
dp[i] = dp[i - 1];
if(s[i] == ‘1‘) {
if(pre[i] == 0) continue;
int a = pre[i],b = pre[a - 1];
if(b == a - 1) continue;
dp[i] = max(dp[a - 2] + i - a,dp[i]);
if(i - a == 1) {
for(int j = b ; j <= a - 2 ; ++j) {
dp[i] = max(dp[j] + a - j - 1,dp[i]);
}
}
}
}
out(dp[N]);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
E - Popping Balls
一道有趣的計數題
就是還是改成二維平面上的點\((A,B)\)求走到\((0,0)\)的路徑
相當於從\((t - 1,0)\)畫一條弧度為\(\frac{3\pi}{4}\)的線和一條垂直於x軸的直線
這兩條直線上方的部分可以往下走
\((s - 1,0)\)同理
然後就相當於,枚舉一個t,從起點走到邊界時第一步是向下(因為如果進入了區域內還左走可以把這個區域往左平移,能走到的地方更多
然後在斜的邊界上找一個點,枚舉一個點\(p,q\)然後往左走走到s的邊界同理,方案數是一個組合數的前綴和
#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 MAXN 4005
#define eps 1e-10
//#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 MOD = 1000000007;
int A,B;
int C[MAXN][MAXN],sum[MAXN][MAXN],s[MAXN][MAXN];
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);
}
void Solve() {
read(A);read(B);
C[0][0] = 1;
sum[0][0] = 1;
for(int i = 1 ; i <= A + B ; ++i) {
C[i][0] = 1;
sum[i][0] = 1;
for(int j = 1 ; j <= i ; ++j) {
C[i][j] = inc(C[i - 1][j],C[i - 1][j - 1]);
sum[i][j] = inc(C[i][j],sum[i][j - 1]);
}
}
for(int j = 0 ; j <= B ; ++j) {
s[j][0] = 1;
for(int i = 1 ; i <= A + B ; ++i) {
s[j][i] = inc(s[j][i - 1],sum[j][min(i,j)]);
}
}
int ans = 0;
for(int t = A; t >= 0 ; --t) {
for(int i = 0 ; i <= t ; ++i) {
int w = C[B - 1][i];
if(!i) update(ans,w);
else {
update(ans,mul(w,s[i - 1][t - i]));
}
}
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
F - Largest Smallest Cyclic Shift
每次找最小的字符和最大的字符組合成一個新的字符串,把這個字符串當成一個新字符插入集合中
直到只剩一種字符
就是每次最小的字符串一定是循環串的開頭,然後從後往前把這個字符串加上一個當前最大的字符串,最大的字符串就越靠前
#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 MAXN 4005
#define eps 1e-10
//#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);
}
struct node {
string s;int num;
friend bool operator < (const node &a,const node &b) {
return a.s < b.s;
}
};
set<node> S;
int x,y,z;
void Solve() {
read(x);read(y);read(z);
if(x) S.insert((node){"a",x});
if(y) S.insert((node){"b",y});
if(z) S.insert((node){"c",z});
while(1) {
if(S.size() == 1) {
node p = *S.begin();
for(int i = 1 ; i <= p.num ; ++i) {
cout << p.s;
}
enter;
break;
}
node s0 = *S.begin(),t0 = *(--S.end());
S.erase(S.begin());S.erase(--S.end());
int k = min(s0.num,t0.num);
S.insert((node){s0.s + t0.s,k});
if(s0.num > k) S.insert((node){s0.s,s0.num - k});
if(t0.num > k) S.insert((node){t0.s,t0.num - k});
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
【AtCoder】CODE FESTIVAL 2017 qual B