A_Phone Desktop
题解,水题一个,不过多阐述,就是说,有两种应用,一种是2x2的,另一种是1x1的,问然后有x个1x1的应用,有y个2x2的,问这些应用最少占据多少屏幕(屏幕为5x3),这题显而易见,2x2的应用一个屏幕里最多放两个,那么我们可以先去y/2先去找2x2的应用占据多少个屏幕,然后留下来7*y/2个1x1应用的空间,然后判断y是奇数还是偶数,如果是奇数屏幕+1.留下空间,再+11,最后再去与x比较,>x说明,就是前面的那些屏幕,少了,就去x-留下空间数量再除以15,并且判断余数,是否需要再去+1
#include<bits/stdc++.h>
using namespace std;
int t;
int x,y;
int cnty,cntx;//cnty统计2x2应用占据的屏幕数
int main()
{
cin>>t;
while(t--)
{
cnty=0,cntx=0;
cin>>x>>y;
cnty=y/2;
int flag=0;
int ansx=cnty*7;
if(y%2!=0){
flag=1;
}
if(flag==1)
{
cnty++;
ansx+=11;
}
if(x<=ansx)
{
printf("%d\n",cnty);
}
else
{
int sum=x-ansx;
int sum1=sum/15;
int sum2=sum%15;
if(sum2!=0)
{
sum1++;
}
printf("%d\n",cnty+sum1);
}
}
return 0;
}
B. Symmetric Encoding
题解:依旧水题一个,唯一难度在于读题,读不懂啥也干不了,小丑的我也是反复读了五六次也是没懂
那么现在来说思路,这题就是说给我一个字符串,找出其中所有出现过的字符,按照字典序去排序,这个就是字符串r,然后将s串,中的每一个字符在r串中找到,然后将其对称的字符变到s串里面,然后模拟一遍直接过
#include<bits/stdc++.h>
using namespace std;
int t;
int n;
char s[200005];
char r[26];
int vis[26];
int main()
{
cin>>t;
while(t--)
{
cin>>n;
memset(vis, 0, sizeof(vis));
cin>>s;
for(int i=0;i<n;i++)
{
int x=s[i]-'a';
vis[x]++;
}
int len=0;
for(int i=0;i<26;i++)
{
if(vis[i]>0)
{
r[len]='a'+i;
len++;
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<len;j++)
{
if(r[j]==s[i])
{
s[i]=r[len-1-j];
break;
}
}
}
cout<<s<<endl;
}
return 0;
}
D. Ingenuity-2
题解:这题也算简单吧,一道模拟题,但是一开始粗心还是错了两次,首先就是先来对什么时候才能有存在的情况进行说明,只有N和S的差为偶数,且E和W的差也为偶数的时候才能有解,别的都不存在解,还有就是在有解的时候,需要判断,每一步都是怎么来的,那么我们以N和S这一对进行说明·,当N和S差为整数时,那么就需要将多出来的除2,然后将多出来的赋给H即可,然后就小于同理,但是在等于0
的时候需要判断,需要将每一次往返赋给一个H或者R
#include <bits/stdc++.h>
using namespace std;
int t;
int n;
string s;
void solve()
{
cin>>n;
int l=0,c=0;
cin>>s;
int f=0;
for(int i=0;i<n;i++){
char x=s[i];
if(x=='N') l++,f=1;
else if(x=='S') l--;
else if(x=='W') c++;
else c--;
}
vector<char> ans(n,'R');
if(abs(c)%2||abs(l)%2)
{//特判奇数
cout<<"NO"<<endl;
return;
}
else{
if(l<0)
{
for(int i=0,cnt=0;i<n;i++)
{
if(cnt==abs(l)/2) break;
if(s[i]=='S'){
ans[i]='H';
cnt++;
}
}
}
else if(l>0)
{
for(int i=0,cnt=0;i<n;i++){
if(cnt==abs(l)/2) break;
if(s[i]=='N'){
ans[i]='H';
cnt++;
}
}
}
else
{
int f1=0,f2=0;//走一步正的走一步负即可
for(int i=0;i<n;i++){
if(s[i]=='S'&&f1==0) ans[i]='H',f1=1;
if(s[i]=='N'&&f2==0) ans[i]='H',f2=1;
}
}
if(l==0&&c==0&&f==1){
//这里特判一种情况,即对于NSEW这种情况,按照上述所述我们会全部赋值为a,
//所以如果存在两个方向都为0,我们判断一下即可
//f则是用于判断竖直等于0是不存在还是因为总和为0的情况
int cnt=0;
for(int i=0;i<n;i++)
{
if(ans[i]=='H') cnt++;
}
if(cnt==0||cnt==n)
{
cout<<"NO"<<endl;
return;
}
for(int i=0;i<n;i++)
cout<<ans[i];
cout<<endl;
return;
}
if(c<0)
{
for(int i=0,cnt=0;i<n;i++)
{
if(cnt==abs(c)/2) break;
if(s[i]=='E')
{
ans[i]='H';
cnt++;
}
}
}
else if(c>0)
{
for(int i=0,cnt=0;i<n;i++)
{
if(cnt==abs(c)/2)
break;
if(s[i]=='W')
{
ans[i]='H';
cnt++;
}
}
}
else
{
int f1=0,f2=0;
for(int i=0;i<n;i++)
{
if(s[i]=='W'&&f1==0) ans[i]='H',f1=1;
if(s[i]=='E'&&f2==0) ans[i]='H',f2=1;
}
}
}
int cnt=0;
for(int i=0;i<n;i++)
{
if(ans[i]=='H') cnt++;
}
if(cnt==0||cnt==n){
cout<<"NO"<<endl;
return;
}
for(int i=0;i<n;i++) cout<<ans[i];
cout<<endl;
}
int main()
{
t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
E. Money Buys Happiness
怎么说呢?经典的01背包问题的变式,难想的点,在于不是要找最小花费的最大价值,而是说,去找最大价值的最小花费
因为题干中说了,花费ci可以大到1e8,但是其价值总共最多1e5,算上最多五十个月,也就1e6的时间复杂度吧,然后我们就先说dp数组的含义,dp[i]代表,在i的价值下,所需要的最小花费
状态转移方程:dp[j]=min(dp[j],dp[j-h[i]]+c[i]);
判断条件:dp[j-h[i]]+c[i]<=x*(i-1)
为啥会是n-1嘞,因为公司是月底发的工资,不要想着一上来白嫖一个月工资
然后就看代码吧
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll t;
ll m,x;
ll c[100005];
ll h[100005];
ll dp[100005];//对于i的幸福,最小的花费费用为dp[i]
ll ans;//统计每个月总的价值
ll maxn;
signed main()
{
cin>>t;
while(t--)
{
for(int i=1;i<=100005;i++)
{
dp[i]=0x3f3f3f3f3f3f3f3f;//求的是最小费用,那么肯定先将其赋值最大值
}
ans=0;
dp[0]=0;
cin>>m>>x;
for(ll i=1;i<=m;i++)
{
cin>>c[i]>>h[i];
ans+=h[i];
}
for(ll i=1;i<=m;i++)
{
for(ll j=ans+5;j>=h[i];j--)
{
if(dp[j-h[i]]+c[i]<=x*(i-1))
{
dp[j]=min(dp[j],dp[j-h[i]]+c[i]);
}
}
}
for(ll j=ans;j>=0;j--)
{
if(dp[j]<=(m-1)*x)
{
printf("%lld\n",j);
break;
}
}
}
return 0;
}
G. Money Buys Less Happiness Now
这题一看就是反悔贪心的板子呢,我们需要去构建一个反悔堆,这里的返回堆用到那个大根堆,每次都将代价放到堆里面,由于每次都是弹出堆顶元素,我们就可以每次都将代价最大的从堆中弹出,最后统计堆中有多少元素即可
ps:这题最后一题我属实没想到,可能官方放错了顺序吧,应该这题放在那个E的前面比较好
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll t;
ll m,x;
ll c[200005];
int main()
{
cin>>t;
while(t--)
{
priority_queue<int> q;
ll sum=0;//用于要统计幸福值
cin>>m>>x;
for(int i=1;i<=m;i++)
{
cin>>c[i];//代价
}
for(int i=1;i<=m;i++)
{
sum-=c[i];
q.push(c[i]);
while(sum<0)
{
sum+=q.top();
q.pop();
}
sum+=x;
}
printf("%lld\n",q.size());
}
return 0;
}