| 题目 | 难度 | 知识点 |
|---|---|---|
| A 真爱粉Tk(一) | ★ | 签到 |
| B 真爱粉Tk(二) | ★ | 签到 |
| C Tk的构造数组 | ★ | 贪心 |
| D 真爱粉Tk(三) | ★★ | 二分 |
| E Tk的染色树 | ★ | 贪心/思维 |
| F Tk的排列间异或 | ★★ | 构造 |
总体感觉不难题目挺有趣的,但是自己打红温了。A题秒wa 后来发现想歪了,影响不大改了过了。B题想了个贪心的做法各种搞发现想歪了,调了很久,看了C过人了看了一下有思路过了,接着调B后来发现直接前后指针就行。心态崩了一大半调了好久,看D有思路调了很久一直没过(此类型的题今天刚做),此时彻底心态崩了想下机了,看了F有思路写wa煎熬,E题脑子宕机随机骗了点分。然后一直调D一直没过,最后10几分钟看了看F发现了正确构造方法过了,D题还是没过(构造的例子都能过就是不过),E题不想看了。最后4题下机。
真爱粉Tk(一)
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
{
LL x; cin>>x;
if((x*10)%25==0) puts("Yes");
else puts("No");
return 0;
}
由于输入的是整数
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
int a[N],t,n;
int main(void)
{
int n; cin>>n;
if(n%5==0) puts("Yes");
else puts("No");
return 0;
}
真爱粉Tk(二)
从最终状态推,一定5再前2在后,那么就看最终状态5的位置中现在有多少个2。这个就是答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
{
int n; cin>>n;
string s; cin>>s;
int cnt2=0,cnt5=0;
for(int i=0;i<n;i++)
if(s[i]=='5') cnt5++;
for(int i=0;i<cnt5;i++)
if(s[i]=='2') cnt2++;
cout<<cnt2;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
int a[N],t,n;
int main(void)
{
int n; cin>>n;
string s; cin>>s;
int ans=0;
int i=-1,j=n;
while(i<j)
{
do i++;while(s[i]=='5');
do j--;while(s[j]=='2');
if(i<j) swap(s[i],s[j]),ans++;
}
cout<<ans;
return 0;
}
Tk的构造数组
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],b[N],ans[N],n;
int main(void)
{
int n; cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
vector< pair<LL,int> >ve1,ve2;
for(int i=1;i<=n;i++)
{
ve1.push_back({a[i]*i,i});
ve2.push_back({b[i],i});
}
sort(ve1.begin(),ve1.end());
sort(ve2.begin(),ve2.end());
map<int,int>mp;
for(int i=0;i<n;i++)
{
mp[ve1[i].second]=ve2[i].second;
}
for(int i=1;i<=n;i++) cout<<b[mp[i]]<<" ";
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],s[N],b[N],n,ans[N];
int main(void)
{
int n; cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],s[i]=i*a[i];
for(int i=1;i<=n;i++) cin>>b[i];
priority_queue< pair<LL,int> >q,q1;
for(int i=1;i<=n;i++)
{
q.push({s[i],i});
q1.push({b[i],i});
}
while(q.size())
{
auto temp=q.top(); q.pop();
auto temp1=q1.top(); q1.pop();
ans[temp.second]=b[temp1.second];
}
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
return 0;
}
真爱粉Tk(三)
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],s[N],cnt2[N],cnt5[N],n,k;
bool check(LL x)
{
LL sum=0,cnt=1,p=0;
for(int i=1;i<=n;i++)
{
if(s[i]>x) return false;
if(sum+s[i]+p*cnt5[i]>x)
{
cnt++;
sum=s[i],p=cnt2[i];
}else sum=sum+s[i]+p*cnt5[i],p+=cnt2[i];
}
return cnt<=k;
}
int main(void)
{
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
string ss; ss=to_string(a[i]);
for(int j=0;j<ss.size();j++)
{
if(ss[j]=='2') cnt2[i]++;
if(ss[j]=='5') cnt5[i]++,s[i]+=cnt2[i];
}
}
LL l=0,r=1e18;
while(l<r)
{
LL mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid+1;
}
cout<<l;
return 0;
}
Tk的染色树
可以发现,答案和叶子有关,偶数的话,选所有叶子便可以。
奇数的话也是全选,那么此时我们是不是还得再选一个点才行,那么从所有中找到最小的数即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*5+10;
LL w[N],d[N],sum,cnt,n;
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=n-1;i++)
{
int a,b; cin>>a>>b;
d[a]++,d[b]++;
}
for(int i=1;i<=n;i++)
if(d[i]<=1) cnt++,sum+=w[i];
if(cnt&1)
{
LL temp=1e12;
for(int i=1;i<=n;i++) temp=min(temp,w[i]);
cout<<sum+temp;
}else cout<<sum;
return 0;
}
Tk的排列间异或
可以发现,只有一种解可以没有使得异或没有任何抵消。那么从大到小找,当前数为0的位置找到都为1的数,便可以没有任何的消耗。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
int a[N],n;
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
map<int,int>mp;
for(int i=n;i>=1;i--)
{
if(mp[i]) continue;
int temp=i,w=1,ans=0;
while(temp)
{
if(temp%2==0) ans+=w;
w=w*2,temp/=2;
}
mp[i]=ans,mp[ans]=i;
}
for(int i=1;i<=n;i++) cout<<mp[a[i]]<<" ";
return 0;
}