codeforces #595.div3 题解

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太菜了,还是要多刷题.......

猜你喜欢

转载自www.cnblogs.com/honey-cat/p/11745599.html
今日推荐