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