Codeforces Round 946 (div3)
- A. Phone Desktop
- 题意:
- 题解:
- 代码:
- Symmetric Encoding
- 题意:
- 题解:
- 代码:
- C. Beautiful Triple Pairs
- 题意:
- 题解:
- 代码:
- Ingenuity-2
- 题意:
- 题解:
- 代码:
- E. Money Buys Happiness
- 题意:
- 题解:
A. Phone Desktop
题意:
有 x x x个 1 ∗ 1 1*1 1∗1和 y y y个 2 ∗ 2 2*2 2∗2的网格,问最少需要多少个 3 ∗ 5 3*5 3∗5的网格可以存下。
题解:
,因为 3 ∗ 5 3*5 3∗5的网格可以由 11 11 11个 1 ∗ 1 1*1 1∗1和 1 1 1个 2 ∗ 2 2*2 2∗2的网格或者 7 7 7个 1 ∗ 1 1*1 1∗1和 2 2 2个 2 ∗ 2 2*2 2∗2的网格或者 15 15 15个 1 ∗ 1 1*1 1∗1的网格构成,所以先根据 2 ∗ 2 2*2 2∗2的数量去判断最少需要多少个网格,然后判断这些网格能否存下 1 ∗ 1 1*1 1∗1的网格,不够就再添加。
代码:
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<vector>
#include<set>
#include<map>
#include<numeric>
#include<functional>
#include<stack>
using namespace std;
typedef long long ll;
void solve()
{int x, y;cin >> x >> y;int s=(y+1)/2;if(s*15-y*4>=x){cout<<s<<endl;}else{s+=(x-(s*15-y*4)+14)/15;cout<<s<<endl;}}
int main()
{ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int t;cin >> t;while (t--) {solve();}return 0;
}
Symmetric Encoding
题意:
存在一种变换操作,有一个原始字符串s,首先构造辅助字符串r,该字符串由字符串s中所有不同的字母组成,按字母顺序书写,然后将s的每一个字符替换成对应r的对称字符。题目给定操作后的字符串,求原始字符串。
题解:
对操作后的字符串去重后排序,然后将给出的字符串对应替换回来即可。
代码:
#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>
#include<map>using namespace std;void solve(){int n;map<char,char> mp;string a;string b;cin>>n>>a;map<char,int> temp;for(int i=0;i<n;i++){if(!mp[a[i]]){b.push_back(a[i]);mp[a[i]]++;}}sort(b.begin(),b.end());int sz=b.size();for(int i=0;i<=sz;i++){mp[b[i]]=b[sz-i-1];}for(int i=0;i<n;i++){cout<<mp[a[i]];}cout<<endl;
}
int main(){int t;cin>>t;while(t--) solve();return 0;
}
C. Beautiful Triple Pairs
题意:
若满足两个三元组[ b i b_{i} bi, b i + 1 b_{i+1} bi+1, b i + 2 b_{i+2} bi+2]和[ c i c_{i} ci, c i + 1 c_{i+1} ci+1, c i + 2 c_{i+2} ci+2]中仅存在两个对应位置的元素相等则这对三元组为好三元组,给出一个数组,问该数组中存在多少个三元组。
题解:
遍历一下数组,用map存储在此之前每种三元组的数量,每次加上可与当前匹配的。最后减去多加上的。
代码:
#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>
#include<map>
#define int long longusing namespace std;const int N=2e5+10;
int a[N];void solve(){int n;int ans=0;cin>>n;for(int i=0;i<n;i++) cin>>a[i];map<pair<int,int>,int> x,y,z;map<vector<int>,int> low;for(int i=0;i+2<n;i++){ans+=x[{a[i],a[i+1]}]++;ans+=y[{a[i],a[i+2]}]++;ans+=z[{a[i+1],a[i+2]}]++;vector<int> v={a[i],a[i+1],a[i+2]};ans-=low[v]*3;low[v]++;}cout<<ans<<endl;
}
signed main(){int t;cin>>t;while(t--) solve();return 0;
}
Ingenuity-2
题意:
有两个棋子,一个为r,另一个为h,初始时都在(0,0),有四种操作(N,S,W,E),N向上移动一格,S向下移动一格,E向右移动一格,W向左移动一格。有n个给定操作,你可自由分配给两个棋子,但不可有一个棋子不移动,问如何分配所有操作两个棋子最终在同一个位置上。
题解:
因为N操作和S操作可以相互抵消,E和W也是如此。
1.如果E和S操作次数的差值无法均分给两个棋子则不存在方案,N和S也是如此。2.当两个同时可以相互抵消时,当操作次数为2时,一定不存在,否则可以将其中一个棋子向一个方向移动一次然后在反方向移动一次,别的操作都分配给另一个棋子,这样在最终两个棋子都在原点。
3.当无法抵消时就均分给两个棋子。
代码:
#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>
#include<map>using namespace std;int t;char inv(char c) {if (c == 'N') return 'S';if (c == 'S') return 'N';if (c == 'E') return 'W';if (c == 'W') return 'E';return ' ';
}int main(){cin >> t;while(t--){int n;cin >> n;string s;cin >> s;string r="R";int x=0,y=0;for(int i=0;i<n;i++){if(s[i]=='N') y+=1;if(s[i]=='S') y-=1;if(s[i]=='E') x+=1;if(s[i]=='W') x-=1;}//计算x,y//初始化全为Rstring ans;for(int i=0;i<n;i++) ans+=r;if(x%2 || y%2) {puts("NO");continue;}if(x==y && y==0){if(n==2) {puts("NO");continue;}//第一个为H,然后找到一个与一个操作相反的操作也为Hans[0]=ans[s.find(inv(s[0]))] = 'H';}else{for(int i=0;i<n;i++){//平分x,yif(s[i]=='N' && y>0) ans[i]='H',y-=2;if(s[i]=='S' && y<0) ans[i]='H',y+=2;if(s[i]=='E' && x>0) ans[i]='H',x-=2;if(s[i]=='W' && x<0) ans[i]='H',x+=2;}}cout << ans << endl;}return 0;
}
E. Money Buys Happiness
题意:
你是一个物理学家。一开始你没有钱,每个月的末尾你会得到 x x x英镑。在第 i i i个月里,你可以付出 c i c_{i} ci英镑,获取 h i h_{i} hi的幸福。在任何时刻你都不能欠钱,问你在m个月过后最多能获得多少幸福。
题解:
#include <bits/stdc++.h>using namespace std;
const int N = 2e6 + 5;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef array<ll, 3> ar;
int mod = 998244353;
const int maxv = 4e6 + 5;
#define endl "\n"void solve()
{int n;cin>>n;ll x;cin>>x;vector<ll> c(n+5),h(n+5);int sum=0;for(int i=1;i<=n;i++) cin>>c[i]>>h[i],sum+=h[i];ll ans=0;vector<ll> dp(sum+5,1E18);dp[0]=0;for(int i=1;i<=n;i++){for(int j=sum+5;j>=h[i];j--){if((i-1)*x>=dp[j-h[i]]+c[i]){dp[j]=min(dp[j],dp[j-h[i]]+c[i]);ans=max(ans,(ll)j);}}}cout<<ans<<endl;
}int main()
{int t;t=1;cin>>t;while(t--){solve();}return 0;
}