Codeforces Round #595(div.3) 题解

codeforces #595 div.3

A Yet Another Dividing into Teams

  • 每个样例中会给出n个不重复数字,由题意相邻数字差的绝对值为1不能在一组则答案只会是1或2,排序后遍历查找相邻数字差的绝对值,若存在值为1,输出2,否则输出1.

B1 Books Exchange (easy version)

  • 数据量较小,直接遍历每个样例中的数组,对每个ai都独立计算一般周期,加入ans数组,最后输出。

B2 Books Exchange (hard version)

  • 相比较b1只有数据约束上的变化,由题意中可以得到不同书本之间会成环,成环的书T同,可以使用一个数组存储初始数据,另外一个数组存储结果。循环遍历第一个数组,c++中的数组会自动初始化为0,使用if(!ans[i])来判断是否计算T,使用和B中相同的方法计算T,之后将同一个环中的书直接赋值(ans[j] = T),最后输出结果即可。
#include<iostream>
#include<vector>
#include<algorithm> 
using namespace std;
int main(void){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int  q,n;
	cin >> q;
	while(q--){
		cin >> n;
		vector<int> arr(n+1);
		vector<int> ans(n+1);//经过点标记 存储答案 
		for(int i=1;i<=n;i++) cin >> arr[i];
		for(int i=1;i<=n;i++){
			if(!ans[i]){
				ans[i] = 1;//i == arr[j] 的那一天完成一个周期 
				//先计算第i个的T T内各本书同周期(成环) 
				for(int j=arr[i];j!=i;j=arr[j]) ans[i]++;
				for(int j=arr[i];j!=i;j=arr[j]) ans[j] = ans[i]; 
			}
		}
		for(int i=1;i<=n;i++) cout << ans[i] << ' ';
		cout << endl;
	} 
	return 0;
} 

C Good Numbers

  • 简单版与困难版区别同上 good number为3进制下每一位都没有2的数字
  • 简单版中直接由n开始枚举,判断函数对每一个数直接模拟出三进制每一位,有2直接返回false
bool check(int t){
 int x;
 while(t){
     x = t%3;
     t /= 3;
     if(x == 2) return false;
 } 
	return true;
}
  • 困难版中先将n转换为3进制,找到最右端的2的位置,再找到这个2之后第一个0,为保证结果最小,将这个0之前所有位上的值全部赋为0,这个0赋值为1。最后将改编后的三进制数转化为十进制输出
#include<iostream>
#include<vector>
using namespace std;
//找规律 good number 应该为三进制下每位数字都不会是2的数 大于等于 n
//循环遍历三进制数组 在三进制中出现2时为保证最小找到其后第一个0
//之前所有位数上归零保证最小 当前位上变为1 保证值增加
int main(void){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int q,pos2;//pos2 记录最右边的2的位置上
	long long n;
	cin >> q;
	while(q--){
		pos2 = -1;
		cin >> n;
		vector<int> th;
		while(n){
			th.push_back(n%3);
			if(th.back() == 2) pos2 = th.size()-1;
			n /= 3;
		}
		th.push_back(0);//可能会出现右端2之后无0的情况 
		if(pos2 != -1){
			for(int i=pos2+1;i<th.size();i++){
				if(th[i] == 0){
					for(int k=0;k<i;k++) th[k] = 0;
					th[i] = 1;
					break;
				}
			}
		}
		long long ans = 0,base = 1;//base 3的各个指数
		for(int i=0;i<th.size();i++){
			ans += th[i]*base;
			base *= 3;
		}
		cout << ans << endl;
	}
	return 0;
}

E By Elevator or Stairs?

  • 动态规划,使用n*2的dp数组来计算 电梯 楼梯分开存储 :ele->st;ele->ele;st->ele;st->st;

  • 状态转移方程 ans为dp数组 0表示使用电梯(等候c) 1 表示使用楼梯

  • 	ans[i][0] = min(ans[i-1][0],ans[i-1][1]+c) + ele[i];
    	ans[i][1] = min(ans[i-1][0],ans[i-1][1]) + st[i];
    

ac代码:

#include<bits/stdc++.h>
using namespace std;
int main(void){
	ios_base::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int n,c;
	cin >> n >> c; //使用电梯等待c 开门 
	vector<int> st(n),ele(n);
	vector<vector<int> > ans(n,vector<int>(2));//n*2 0选择电梯 或者 1楼梯 
	n--;//第一层为0  
	for(int i=1;i<=n;i++) cin >> st[i];
	for(int i=1;i<=n;i++) cin >> ele[i];
	ans[0][0] = c;ans[0][1] = 0;
	//电梯 楼梯分开存储 ele->st;ele->ele;st->ele;st->st; 
	for(int i=1;i<=n;i++){
		ans[i][0] = min(ans[i-1][0],ans[i-1][1]+c) + ele[i];
		ans[i][1] = min(ans[i-1][0],ans[i-1][1]) + st[i];
	}
	//为什么出电梯不用等开门?? 
	for(int i=0;i<=n;i++) cout << min(ans[i][0],ans[i][1]) << ' ';
	cout << endl;
	return 0;
}

wo太菜了,还是要多刷题.......

posted @ 2019-10-26 21:17  jimmy-cat  阅读(359)  评论(0编辑  收藏  举报