• 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一下当前最小值就算出来了。

    代码略没写

  • 相关阅读:
    0817JavaScript--------------循环语句
    MySQL数据库的几种引擎
    spring-boot+mybatisPlus+shiro的集成demo 我用了5天
    Nginx 自定义404、500、502 页面
    论Photoshop的正确安装姿势
    记定位一次多线程数据安全问题
    记服务器被黑客攻击事件(肉鸡)
    Spring-Boot 使用 Jedis 操作 Redis
    JavaScript 中 replace方法 替换所有字符串
    关于图文转换的web工具
  • 原文地址:https://www.cnblogs.com/Mychael/p/12852972.html
Copyright © 2020-2023  润新知