zoukankan      html  css  js  c++  java
  • 2020.5.6 Codeforces Round #639 (Div. 2)比赛记录

    比赛链接

    A Puzzle Pieces

    就是问用题中特定形状的拼图能不能拼出(n imes m)的矩形
    分析一下可以发现,如果(n=1)或者(m=1)肯定是可以的
    然后发现最大的块就是(2 imes 2)了,也就是说n和m在其它情况都不能大于2

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<map>
    #include<set>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define cls(s,v) memset(s,v,sizeof(s))
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cp pair<int,int>
    using namespace std;
    const int maxn = 100005,maxm = 100005,INF = 0x3f3f3f3f;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    	return flag ? out : -out;
    }
    
    int main(){
    	int T = read(),n,m;
    	while (T--){
    		n = read(); m = read();
    		if (n == 1 || m == 1) puts("YES");
    		else if (n <= 2 && m <= 2) puts("YES");
    		else puts("NO");
    	}
    	return 0;
    }
    

    B Card Constructions

    简单题

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<map>
    #include<set>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define cls(s,v) memset(s,v,sizeof(s))
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cp pair<int,int>
    using namespace std;
    const int maxn = 100005,maxm = 100005,INF = 0x3f3f3f3f;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    	return flag ? out : -out;
    }
    int f[maxn],m;
    int main(){
    	for (m = 1; f[m - 1] <= 1000000000; m++) f[m] = f[m - 1] + 3 * m - 1; 
    	m--;
    	int T = read();
    	while (T--){
    		int n = read(),ans = 0;
    		for (int i = m; i; i--){
    			//cout << f[i] << endl;
    			while (f[i] <= n) n -= f[i],ans++;
    		}
    		printf("%d
    ",ans);
    	}
    	
    	return 0;
    }
    

    C Hilbert's Hotel

    题意是有无穷个房间,标号为全体整数,现在以(n)为周期进行调整,在每个周期内模(n)(k)的房间的客人向前移动(a_k)个房间【(a_k)可能为负】,问是否会有客人冲突。
    显然,如果(0)(n - 1)通过(a_k)变换形成一个与(0)(n-1)一一对应的映射,那么对于移动后的每个房间,都唯一对应一个开始的位置,没有冲突。
    一但形成的映射不是一一对应的,那么一定会有房间冲突。

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<map>
    #include<set>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define cls(s,v) memset(s,v,sizeof(s))
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cp pair<int,int>
    using namespace std;
    const int maxn = 200005,maxm = 100005,INF = 0x3f3f3f3f;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    	return flag ? out : -out;
    }
    int vis[maxn];
    int main(){
    	int T = read();
    	while (T--){
    		int n = read(),flag = true;
    		for (int i = 0; i < n; i++) vis[i] = 0;
    		for (int i = 0; i < n; i++){
    			int x = read();
    			if (vis[((i + x) % n + n) % n]) flag = false;
    			vis[((i + x) % n + n) % n] = true;
    		}
    		puts(flag ? "YES" : "NO");
    	}
    	return 0;
    }
    

    D Monopole Magnets

    题意是有一个(n*m)的矩阵,你可以向其中每个位置放置任意个黑点和白点。符合如下规则:
    1、每一列每一行必须有白点
    2、所有黑点可以向同一行或同一列的白点所在方向移动任意格。要求带#点必须可以被移动到,剩余带.点必须不能被移动到。
    求最少需要多少黑点,或者无解。

    分析发现,任意#之间的路径可达,如果两个#之间存在.,那么一定是不合法的。也就是说,#形成的联通块是凸的。
    其次如果存在一行全为.且任意一列都有#,那么不合法。因为那一行一定要放置白点,无论放置在哪都会导致该列#处的黑点到达。
    然后数一数#联通块个数就是答案了

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<map>
    #include<set>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define cls(s,v) memset(s,v,sizeof(s))
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cp pair<int,int>
    using namespace std;
    const int maxn = 1005,maxm = 100005,INF = 0x3f3f3f3f;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    	return flag ? out : -out;
    }
    int n,m;
    char s[maxn][maxn];
    int sumr[maxn][maxn],sumc[maxn][maxn];
    int visr[maxn],visc[maxn];
    int vis[maxn][maxn],cnt;
    int X[] = {0,0,-1,1},Y[] = {-1,1,0,0};
    void dfs(int x,int y){
    	vis[x][y] = true;
    	for (int k = 0; k < 4; k++){
    		int nx = x + X[k],ny = y + Y[k];
    		if (s[nx][ny] == '#' && !vis[nx][ny]) dfs(nx,ny);
    	}
    }
    int main(){
    	n = read(); m = read();
    	char c = getchar();
    	REP(i,n) REP(j,m){
    		while (c != '#' && c != '.') c = getchar();
    		s[i][j] = c;
    		c = getchar();
    	}
    	REP(i,n) REP(j,m){
    		sumr[i][j] = sumr[i][j - 1];
    		sumc[i][j] = sumc[i - 1][j];
    		if (s[i][j] == '#'){
    			if (!vis[i][j]) cnt++,dfs(i,j);
    			sumr[i][j]++; sumc[i][j]++;
    			visr[i] = true; visc[j] = true;
    		}
    	}
    	int flag = true;
    	//1
    	REP(i,n) REP(j,m){
    		if (s[i][j] == '.'){
    			if (sumr[i][j] && sumr[i][m] > sumr[i][j]) flag = false;
    			if (sumc[i][j] && sumc[n][j] > sumc[i][j]) flag = false;
    		}
    	}
    	//2
    	int tagr = false,tagc = false;
    	REP(i,n) if (!visr[i]) tagr = true;
    	REP(j,m) if (!visc[j]) tagc = true;
    	if (!tagc) REP(i,n) if (!sumr[i][m]) flag = false;
    	if (!tagr) REP(j,m) if (!sumc[n][j]) flag = false;
    	if (!flag) puts("-1");
    	else printf("%d
    ",cnt);
    	return 0;
    }
    

    E Quantifier Question

    【当天cf一直in queue,写到这题就停了,但大概想到做法了】
    题意是给出一个公式包含(n)变量的若干个((x_i < x_j))的合取的形式,要求给出一个合适的量词,使得公式为真。
    量词中(x_i)顺序固定,要求使用尽量多的全称量词(forall)

    首先我们发现,一个((x_i <x_j))中,假如(i < j),那么(forall x_j)一定不合法,因为(x_i)在这之前已经固定,存在(x_j)使得式子不成立。
    所以一开始我们就能确定一些(x_i)必须取量词(exists x_i)
    对于剩余的,由于不等式的传递性,我们可以进行建图,那么这个图一定是拓扑图,否则公式永假。
    然后对于图上每一条路径,形成一个不等关系,路径上每两点之间的不等关系就确定了,同上分析,只有最小的点能取(forall)
    那么问题就简单了,只要统计有多少点是进过其路径上编号最小的点。在拓扑图上正着反着dp一下当前最小值就算出来了。

    代码略没写

  • 相关阅读:
    HDU 1495 非常可乐
    ja
    Codeforces Good Bye 2016 E. New Year and Old Subsequence
    The 2019 Asia Nanchang First Round Online Programming Contest
    Educational Codeforces Round 72 (Rated for Div. 2)
    Codeforces Round #583 (Div. 1 + Div. 2, based on Olympiad of Metropolises)
    AtCoder Regular Contest 102
    AtCoder Regular Contest 103
    POJ1741 Tree(点分治)
    洛谷P2634 [国家集训队]聪聪可可(点分治)
  • 原文地址:https://www.cnblogs.com/Mychael/p/12852972.html
Copyright © 2011-2022 走看看