zoukankan      html  css  js  c++  java
  • 【AtCoder】CODE FESTIVAL 2017 qual A

    A - Snuke's favorite YAKINIKU

    ……

    #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('
    ')
    #define MAXN 40005
    #define eps 1e-12
    //#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);
    }
    string s;
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	cin >> s;
    	if(s.substr(0,4) == "YAKI") puts("Yes");
    	else puts("No");
    }
    

    B - fLIP

    枚举N有几个按了,M有几列按了
    对于一个点,行和列只有一个按了,那么这个点是黑的

    #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('
    ')
    #define MAXN 40005
    #define eps 1e-12
    //#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,K;
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	read(N);read(M);read(K);
    	for(int i = 0 ; i <= N ; ++i) {
    		for(int j = 0 ; j <= M ; ++j) {
    			int res = i * (M - j) + (N - i) * j;
    			if(res == K) {puts("Yes");return 0;}
    		}
    	}
    	puts("No");
    	return 0;
    }
    

    C - Palindromic Matrix

    从最外一圈开始推,我们输出需要几个4个一样的,2个一样的,可能还有需要1个单个的
    然后用每个字母开始填4个一样的,再填2个一样的,再填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('
    ')
    #define MAXN 40005
    #define eps 1e-12
    //#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;
    int num[30],cnt[10];
    char s[105][105];
    
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	read(N);read(M);
    	for(int i = 1 ; i <= N ; ++i) {
    		scanf("%s",s[i] + 1);
    	}
    	for(int i = 1 ; i <= N ; ++i) {
    		for(int j = 1 ; j <= M ; ++j) {
    			num[s[i][j] - 'a']++;
    		}
    	}
    	int lr = 1,rr = N,lc = 1,rc = M;
    	while(lr <= rr && lc <= rc) {
    		int r = 0;
    		if(lr != rr) r += 2;
    		if(lc != rc) r += 2;
    		if(!r) r = 1;
    		cnt[r]++;
    	 	for(int i = 1 ; i <= N ; ++i) {
    			if(lr + i <= rr - i) {
    				int r = 0;
    				if(lr + i != rr - i) r += 2;
    				if(lc != rc) r += 2;
    				cnt[r]++;
    			}
    			else break;
    		}
    		for(int i = 1 ; i <= M ; ++i) {
    			if(lc + i <= rc - i) {
    				int r = 0;
    				if(lc + i != rc - i) r += 2;
    				if(rr != lr) r += 2;
    				cnt[r]++;
    			}
    			else break;
    		}
    		++lr;--rr;++lc;--rc;
    	}
    	for(int i = 0 ; i < 26 ; ++i) {
    		while(cnt[4] && num[i] >= 4) {num[i] -= 4;--cnt[4];}
    		while(cnt[2] && num[i] >= 2) {num[i] -= 2;--cnt[2];}
    		while(cnt[1] && num[i] >= 1) {num[i] -= 1;--cnt[1];}
    	}
    	if(cnt[1] || cnt[2] || cnt[4]) puts("No");
    	else puts("Yes");
    	return 0;
    }
    

    D - Four Coloring

    把图旋转45度后,再放一个每块大小是d*d的方格,然后一行用RB间隔染色,下一行用GY间隔染色

    #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('
    ')
    #define MAXN 200005
    #define eps 1e-12
    //#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 H,W,d;
    bool vis[1005][1005];
    string s = "RBGY";
    void Solve() {
    	read(H);read(W);read(d);
    	for(int i = 1 ; i <= H ; ++i) {
    		for(int j = 1 ; j <= W ; ++j) {
    			int t = 0;
    			if((i + j - 1) / d & 1) t |= 2;
    			if((i - j + 500 - 1) / d & 1) t |= 1;
    			putchar(s[t]);
    		}
    		enter;
    	}
    }
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	Solve();
    }
    

    E - Modern Painting

    第一次肯定是一个竖直的完整画下来,或者一个水平的完整的画下来
    用竖直的举例
    就是枚举一个区间([L,R])都是完整的竖直画下来,方案数是2的这个区间上下都有人的列个数次幂
    然后算前后的那一块方案数
    肯定是先横着一刀,再竖着一刀,再横着一刀
    我们把横着的轮廓线画出来,再把一边的翻过去,发现是一个路径计数,但是要求对称轴必须有一个竖线
    加入竖直有X个人,上有Y人,下有Z人,那么如果直接走过去,方案数是
    (inom{X + Y + Z}{X})
    那我们考虑一个序列,我们就走(X - 1)个竖直的,横向走到对称轴后,紧接着就添加一个竖直的
    方案数就是
    (inom{X + Y + Z - 1}{X - 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('
    ')
    #define MAXN 200500
    #define eps 1e-12
    //#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 = 998244353;
    int N,M;
    char a[4][MAXN];
    int fac[MAXN * 2],invfac[MAXN * 2],f[MAXN],b[MAXN],sum[4][MAXN],s[MAXN];
    int pw[MAXN],ipw[MAXN],ans;
    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;
    }
    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 update(int &x,int y) {
    	x = inc(x,y);
    }
    int C(int n,int m) {
    	if(n < m) return 0;
    	return mul(fac[n],mul(invfac[m],invfac[n - m]));
    }
    void CalcV() {
    	memset(f,0,sizeof(f));
    	memset(b,0,sizeof(b));
    	memset(s,0,sizeof(s));
    	int X = sum[0][N],Y,Z;
    	for(int i = 0 ; i <= M ; ++i) {
    		if(a[2][i + 1] == '0' && a[3][i + 1] == '0') continue;
    		Y = sum[2][i],Z = sum[3][i];
    		if(!X) {
    			if(Y == 0 && Z == 0) f[i] = 1;
    			else f[i] = 0;
    		}
    		else {
    			f[i] = C(X + Y + Z - 1,X - 1);
    		}
    	}
    	X = sum[1][N];
    	for(int i = M + 1 ; i >= 1 ; --i) {
    		if(a[2][i - 1] == '0' && a[3][i - 1] == '0') continue;
    	 	Y = sum[2][M] - sum[2][i - 1],Z = sum[3][M] - sum[3][i - 1];
    		if(!X) {
    			if(Y == 0 && Z == 0) b[i] = 1;
    			else b[i] = 0;
    		}
    		else {
    			b[i] = C(X + Y + Z - 1,X - 1);
    		}
    	}
    	for(int i = 1 ; i <= M ; ++i) s[i] = s[i - 1] + (a[2][i] == '1' && a[3][i] == '1');
    	for(int i = 0 ; i <= M ; ++i) {
    		f[i] = mul(f[i],ipw[s[i]]);
    	}
    	for(int i = M + 1 ; i >= 1 ; --i) {
    		b[i] = inc(b[i + 1],mul(b[i],pw[s[i - 1]]));
    	}
    	for(int i = 1 ; i <= M ; ++i) {
    		update(ans,mul(f[i - 1],b[i + 1]));
    	}
    }
    void CalcH() {
    	memset(f,0,sizeof(f));
    	memset(b,0,sizeof(b));
    	memset(s,0,sizeof(s));
    	int X = sum[2][M],Y,Z;
    	for(int i = 0 ; i <= N ; ++i) {
    		if(a[0][i + 1] == '0' && a[1][i + 1] == '0') continue;
    		Y = sum[0][i],Z = sum[1][i];
    		if(!X) {
    			if(Y == 0 && Z == 0) f[i] = 1;
    			else f[i] = 0;
    		}
    		else {
    			f[i] = C(X + Y + Z - 1,X - 1);
    		}
    	}
    	X = sum[3][M];
    	for(int i = N + 1 ; i >= 1 ; --i) {
    		if(a[0][i - 1] == '0' && a[1][i - 1] == '0') continue;
    		Y = sum[0][N] - sum[0][i - 1],Z = sum[1][N] - sum[1][i - 1];
    		if(!X) {
    			if(Y == 0 && Z == 0) b[i] = 1;
    			else b[i] = 0;
    		}
    		else {
    			b[i] = C(X + Y + Z - 1,X - 1);
    		}
    	}
    	for(int i = 1 ; i <= N ; ++i) s[i] = s[i - 1] + (a[0][i] == '1' && a[1][i] == '1');
    	for(int i = 0 ; i <= N ; ++i) {
    		f[i] = mul(f[i],ipw[s[i]]);
    	}
    	for(int i = N + 1 ; i >= 1 ; --i) {
    		b[i] = inc(b[i + 1],mul(b[i],pw[s[i - 1]]));
    	}
    	for(int i = 1 ; i <= N ; i++) {
    		update(ans,mul(f[i - 1],b[i + 1]));
    	}
    }
    void Solve() {
    	read(N);read(M);
    	for(int i = 0 ; i <= 3 ; ++i) scanf("%s",a[i] + 1);
    	for(int i = 0 ; i <= 3 ; ++i) {
    		int T = (i <= 1 ? N : M);
    		for(int j = 1 ; j <= T ; ++j) {
    			sum[i][j] = sum[i][j - 1] + (a[i][j] == '1');
    		}
    	}
    	int T = 2 * (N + M) + 10;
    	fac[0] = 1;
    	for(int i = 1 ; i <= T ; ++i) {
    		fac[i] = mul(fac[i - 1],i);
    	}
    	invfac[T] = fpow(fac[T],MOD - 2);
    	for(int i = T - 1 ; i >= 0 ; --i) {
    		invfac[i] = mul(invfac[i + 1],i + 1);
    	}
    	pw[0] = 1;
    	T = max(N,M);
    	for(int i = 1 ; i <= T ; ++i) {
    		pw[i] = mul(pw[i - 1],2);
    	}
    	ipw[0] = 1;
    	for(int i = 1 ; i <= T ; ++i) {
    		ipw[i] = mul(ipw[i - 1],(MOD + 1) / 2);
    	}
    	CalcV();
    	CalcH();
    	if(!sum[0][N] && !sum[1][N] && !sum[2][M] && !sum[3][M]) ans = 1;
    	out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	Solve();
    }
    

    F - Squeezing Slimes

    对于一个单个的区间来说,我们可以用
    如果(a = 2^{k})能用k次合成
    如果(2^{k} < a < 2^{k + 1}),能用k+1次合成
    我们记录一下每个区间最左的元素被选了几次,最右的区间选了几次
    如果是(a = 2^{k}),那么两边就选了k次
    另一种有两个情况,左边k次右边k+1次,左边k+1次右边k次
    每个相邻的地方可以减少(min(r_{i},l_{i + 1}))
    用一个dp实现就行

    #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('
    ')
    #define MAXN 100005
    #define eps 1e-12
    //#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;
    int a[MAXN],cnt[MAXN],val[MAXN][2];
    int64 dp[MAXN][2];
    void Solve() {
    	read(N);
    	for(int i = 1 ; i <= N ; ++i) {
    		read(a[i]);
    		int k = -1,x = a[i];
    		while(x) {++k;x >>= 1;}
    		cnt[i] = k;
    	}
    	for(int i = 1 ; i <= N ; ++i) {
    		dp[i][0] = 1e16;dp[i][1] = 1e16;
    		int s = cnt[i],t = cnt[i];
    		if(a[i] != (1 << cnt[i])) ++t;
    		val[i][0] = s;val[i][1] = t;
    		for(int j = 0 ; j <= 1 ; ++j) {
    			dp[i][0] = min(dp[i][0],dp[i - 1][j] + t - min(t,val[i - 1][j]));
    			dp[i][1] = min(dp[i][1],dp[i - 1][j] + t - min(s,val[i - 1][j]));
    		}
    	}
    	out(min(dp[N][0],dp[N][1]));enter;
    }
    int main() {
    #ifdef ivorysi
    	freopen("f1.in","r",stdin);
    #endif
    	Solve();
    }
    
  • 相关阅读:
    堆栈(线性表)
    链表 -- 循环链表(线性表)
    链表 -- 单向链表(线性表)
    排序算法--归并算法(强分治)
    sqlhelper
    sqlite与sqlserver区别
    常用sql集锦
    外出实施问题总结
    JS深入理解系列(一):编写高质量代码
    通用分页(Jquery版)
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10363997.html
Copyright © 2011-2022 走看看