Codeforces Round #617 (Div. 3)题解
A. Array with Odd Sum
题意:
给一个数组,你可以无限次将某个位置上的数变成一个其他位置上的数,问是否可以通过操作使该数组的和变成奇数
思路:
如果数组的和原本就为奇数,直接输出YES。否则,如果我们有最少一个奇数与一个偶数的时候也可以
#include<iostream> #include<algorithm> using namespace std; int main(){ int t; scanf("%d",&t); while(t--) { long long sum=0; int n,ok1=0,ok2=0; cin>>n; for(int i=1,temp;i<=n;i++){ cin>>temp; sum+=temp; if(temp%2) ok1=1; else ok2=1; } if(sum%2) cout<<"YES\n"; else if(ok1&&ok2) cout<<"YES\n"; else cout<<"NO\n"; } }
B. Food Buying
题意:
一开始你有n元,每次你花费x元,你可以获得⌊x/10⌋元,问你最多能花多少钱
思路:
按照贪心的想法,每次花费10元钱是最合算的,所以每次你都尽可能的花10x的钱,不断执行这个操作,直到最后的钱数少于10,再将最后的钱加上即为答案
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; int main() { int t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); ll ret=0; while(n>=10){ ret+=n/10*10; n=n%10+n/10; } ret+=n; cout<<ret<<endl; } return 0; }
C. Yet Another Walking Robot
思路:
用个mapmap记录一下走到某一坐标的最晚时刻,然后直接维护答案就行。
#include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath> #include <set> #include <map> #include <queue> #include <iomanip> #define MP make_pair #define fi first #define se second #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() #define INF 0x3f3f3f3f #define Local #ifdef Local #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0) void err() { std::cout << '\n'; } template<typename T, typename...Args> void err(T a, Args...args) { std::cout << a << ' '; err(args...); } #else #define dbg(...) #endif void pt() {std::cout << '\n'; } template<typename T, typename...Args> void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); } using namespace std; typedef long long ll; typedef pair<int, int> pii; //head const int N = 2e5 + 5; int n; char s[N]; void run(){ cin >> n >> (s + 1); map <int, map<int, int>> mp; int x = 0, y = 0; mp[x][y] = 0; int ans = INF, l, r; for(int i = 1; i <= n; i++) { if(s[i] == 'L') --x; if(s[i] == 'R') ++x; if(s[i] == 'U') ++y; if(s[i] == 'D') --y; if(mp[x].find(y) == mp[x].end()) { mp[x][y] = i; } else { if(i - mp[x][y] < ans) { ans = i - mp[x][y]; l = mp[x][y] + 1, r = i; } mp[x][y] = i; } } if(ans == INF) cout << -1 << '\n'; else cout << l << ' ' << r << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(20); int T; cin >> T; while(T--) run(); return 0; }
D. Fight with Monsters
题意:
有n个怪兽每个怪兽都有其血量,你和你的对手每次轮流(你先手)攻击怪兽分别可造成a,b点的伤害,如果是你杀死怪兽你可得1分,并且你可以有k次的机会跳过对手的攻击回合,问你最多可以得几分
思路:
先计算出不用跳过就能得分的次数,用h%(a+b)<=a判断(注意特判为0的情况),然后计算要杀死其他怪兽必须跳过几次对手的回合丢到一个vector里,排序一下贪心即可
#include<iostream> #include<algorithm> #include<vector> using namespace std; const int maxn=2e5+10; int c[maxn],n,a,b,k; vector<int> d; int main() { scanf("%d%d%d%d",&n,&a,&b,&k); for(int i=1;i<=n;i++) scanf("%d",&c[i]); int ans=0; for(int i=1;i<=n;i++){ if((c[i]%(a+b))<=a&&(c[i]%(a+b))!=0) ans++; else if((c[i]%(a+b))==0){ if(b%a==0) d.push_back(b/a); else d.push_back(b/a+1); } else{ int x; if((c[i]%(a+b))%a) x=(c[i]%(a+b))/a; else x=(c[i]%(a+b))/a-1; d.push_back(x); } } sort(d.begin(),d.end()); for(int i=0;i<d.size();i++){ if(k-d[i]>=0) ans++,k-=d[i]; else break; } cout<<ans<<endl; }
E1. String Coloring (easy version)
题意:
对字符串进行染色,可以每个字符可以染成两种颜色中的一种,相邻的两个颜色不同的字符可交换位置,问是否有一种染色方案在交换后可以使字符串变成按字典序非下降序列
思路:
转化一下题意变成该字符串时候能分成两个不下降的子序列,贪心做法,可以开两个字符串,判断当前位置的字符是否大于等于两个字符串尾端的字符,如果都无法加入则输出NO
#include<iostream> #include<algorithm> using namespace std; const int maxn=205; int ans[maxn]; int main() { int n; string s; cin>>n>>s; char last1='a',last2='a'; for(int i=0;i<n;i++){ if(s[i]>=last1){ ans[i]=0; last1=s[i]; continue; } if(s[i]>=last2){ ans[i]=1; last2=s[i]; continue; } cout<<"NO"<<endl; return 0; } cout<<"YES"<<endl; for(int i=0;i<n;i++) cout<<ans[i]; cout<<endl; return 0; }