• 题解 Educational Codeforces Round 84 (Rated for Div. 2) A


    侃侃:

    之后做的题,发现几天不做题,脑子都不够用了,基本的模拟都不会写了,可能本来就菜吧。
    做了做前三道基本的题,发现也不简单呀!
    

    A. Sum of Odd Integers

    题目大意:

    给一个整数,再给一个 k ,问这个数是否可以由几个 不同的 奇数和 得到?
    

    考察点:

    奇数偶数的性质,以及你的推导能力。
    

    坑点:

    1、两个数相乘可能会 爆 int,所以需要用 long long
    2、需要特判 k * k > n,首先一定要有 k 个奇数,如果这几个最小的奇数
       都比 n 大了,那么必然是无法得到的。
    

    Code:

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
     
    using namespace std;
     
    int main(void) {
    	long long  t,n,k;
    	cin >> t;
    	while(t --) {
    		cin >> n >> k;
    		// k 个不同的奇数能表示的最小数 是 k * k 
    		if(k > n || n < k * k) cout << "NO" << endl;
                    // 分奇数偶数情况进行讨论
    		else if(n & 1) {
    			if(k & 1) cout << "YES" << endl;
    			else cout << "NO" << endl; 
    		} else {
    			if(k & 1) cout << "NO" << endl;
    			else cout << "YES" << endl;
    		}
    	}
    	return 0;
    } 
    

    B. Princesses and Princes

    题目大意:

    公主和王子进行匹配,每个公主可以有一个王子的候选名单,王子名单的价值是按照价值从大
    到小已经排好序的,当然,每个公主只能选择一个王子,最后如果所有公主和王子都可以成功
    匹配,那么就不用增加了,否则找到一个未配对的公主,然后再寻找一个未配对的王子,两个进
    行配对。
    

    侃侃:

    刚开始一看图以为是二分图匹配,但更扯淡的是这道题的介绍也太长了,英文水平实在有限,
    不得不使用辅助工具、
    还有就是一些细节需要注意,尤其是 0 的情况,例如第二个样例。
    

    Code:

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
     
    #define INF 0x3f3f3f3f
     
    using namespace std;
     
    const int maxn = 1e5 + 10;
     
    int vis[maxn],cnt[maxn];
     
    int t,n,op,g;
     
    int main(void) {
    	scanf("%d",&t);
    	while(t --) {
    		scanf("%d",&n);
    		memset(vis,0,sizeof(vis));
    		bool flag = false;
    		int pos1 = -1,pos2;
    		for(int i = 1; i <= n; i ++) {
    			scanf("%d",&op);
    			// 为什么不在这里进行取最小值进行判断,太过麻烦,而且有可能 op = 0 
    			for(int k = 1; k <= op; k ++) {
    				scanf("%d",&cnt[k]);
    			}
    			int v = 0;
    			// 选择一个合适的王子进行配对(没有被其他人选过) 
    			for(int k = 1; k <= op; k ++) {
    				if(vis[cnt[k]] == 0) {
    					vis[cnt[k]] = 1;
    					v = 1;
    					break;
    				}
    			}
    			// 如果已经找到一个值,那么之后就不需要再找了 
    			if(pos1 != -1) continue;
    			if(v == 0) {
    				pos1 = i;
    			}
    		}
    		
    		for(int i = 1; i <= n; i ++) {
    			if(vis[i]) continue;
    			pos2 = i;
    			break; 
    		}
    		
    		if(pos1 != -1) {
    			printf("IMPROVE
    ");
    			printf("%d %d
    ",pos1,pos2);
    		} else {
    			printf("OPTIMAL
    ");
    		}
    	}
    	return 0;
    }
    

    C. Game with Chips

    题目大意:

    有一个 n * m 的矩阵,之后给一些起点和终点,问最后每个起点和终点重合需要
    走多少步,打印其路径。
    

    侃侃:

    题目说我们最多不能超过 2 * n * m 步,那么我们首先可以得到一个信息就是
    我们走完 整个矩阵只需要 n * m 步。
    这道题比较良心的是并没有要求我们走的是最小步数,而且题目中还用加粗强调了
    多个起点可以在同一个地方(我一定是瞎了,不,我可能暂时还没学会根据题目给的
    信息去做推导),我们可以把所有的起点都放到同一个角落,然后从起点走完整个
    矩阵就可以了(这方法真的是巧妙,我怎么就想不到呢?)
    

    细节:

    第一次将所有点都归置到一个角落:
    n + m - 2
    第二次走完矩阵:
    n *m - 1
    
    n + m + n * m - 1 < 2 * n * m
    必然满足题目的要求。
    

    Code:

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 205;
    
    int a[maxn][maxn],vis[maxn][maxn];
    
    int dir[][2] = {{1,0},{-1,0},{0,1},{0,-1}};
    
    string road;
    
    int n,m,k;
    
    int x,y,u,v;
    
    void DFS(int sx,int sy) {
    	vis[sx][sy] = 1;
    	for(int i = 0; i < 4;  i ++) {
    		int x = sx + dir[i][0];
    		int y = sy + dir[i][1];
    
    		if(x < 1 || y < 1 || x > n || y > m) continue;
    		if(vis[x][y]) continue;
    		vis[x][y] = 1;
    		if(dir[i][0] == 1 && dir[i][1] == 0) {
    			road += 'D';
    			DFS(x,y);
    		} else if(dir[i][0] == -1 && dir[i][1] == 0) {
    			road += 'U';
    			DFS(x,y);
    		} else if(dir[i][0] == 0 && dir[i][1] == 1) {
    			road += 'R';
    			DFS(x,y);
    		} else if(dir[i][0] == 0 && dir[i][1] == -1) {
    			road += 'L';
    			DFS(x,y);
    		}
    	}
    	return ;
    }
    
    int main(void) {
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i = 1; i <= k ; i ++) {
    		scanf("%d%d",&x,&y);
    	}
    	for(int j = 1; j <= k ; j ++) {
    		scanf("%d%d",&u,&v);
    	}
    
    	for(int i = 1; i < n; i ++) {
    		road += 'U';
    	}
    	for(int j = 1; j < m; j ++) {
    		road += 'L';
    	}
    
    	DFS(1,1);
    
    	printf("%d
    ",road.size());
    	cout << road << endl;
    	return 0;
    }
    

    后记:

    一般来说 CF 的前几道题都是比较基础的,突然发现自己学的很多算法都没有用上,
    难道是老了,思维跟不上?那一定是自己太菜了。
    读题真的是十分重要的,很多细节都会通过题意表达出来,吃一堑,长一智,以后做题的
    时候先将所有的细节标注下来,尤其是黑体强调的东西。
    还有,乘法一定要记得 long long .
    
    加油!自信一点。
  • 相关阅读:
    Django Restframework 实践(二)
    mysql in 过滤 解决转义问题
    automapper
    autoface
    各种文件上传 转载
    REST Client
    MySql PartionBy
    mysql 变量名称不能与表字段一致
    mysql 存储过程分页 转载
    dapper.net 转载
  • 原文地址:https://www.cnblogs.com/prjruckyone/p/12560484.html
Copyright © 2020-2023  润新知