A:https://codeforces.com/contest/1706/problem/A
抓住几个要点:1、A在越在前面越小;2、位置i和m-a[i]+1,在前面的一位没变的话,先变前面的,前面一位已经变成A,就变后面的那位;3、模拟加油。
#include<bits/stdc++.h>//实在写得太长了,我自己都很难愿意再看一遍
using namespace std;
int b[20005],a[20005];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(a,0,sizeof(a));
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>b[i];
string s(m,'B');
s=" "+s;
for(int i=0;i<n;i++)
{
if(b[i]<(m-b[i]+1)&&a[b[i]]==0)
s.replace(b[i],1,"A"),
a[b[i]]=1;
else
{
if(b[i]>=(m-b[i]+1)&&a[m-b[i]+1]==0)
{
s.replace(m-b[i]+1,1,"A");
a[m-b[i]+1]=1;
continue;
}
if(a[b[i]]==1)
{
s.replace(m-b[i]+1,1,"A");
a[m-b[i]+1]=1;
}
else s.replace(b[i],1,"A");
}
}
s.erase(0,1);
cout<<s<<'\n';
}
}//好吧,我又看了一遍
B题:https://codeforces.com/contest/1706/problem/B
方法挺多的,但我不会。这个方法算听懂了。
第一次放就自成一体,第二次放的话,如果和上次的那块之间有偶数块,就可以与第一次放的成为一派。
#include<bits/stdc++.h>
using namespace std;
int a[200005],b[200005],vis[200005];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(vis,0,sizeof(vis));
memset(a,0,sizeof(a));
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>b[i];
for(int i=1;i<=n;i++)
{
if(vis[b[i]]==0)
{
a[b[i]]++;
vis[b[i]]=i;
}
else if((i-vis[b[i]]-1)%2==0)
{
a[b[i]]++;
vis[b[i]]=i;
}
}
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
puts("");
}
}
C题:https://codeforces.com/contest/1706/problem/C
n为奇数,取第偶数个即可。
n为偶数,变化较大。可能存在一个房子的后两个房子都不为清凉住房;
例:
房子:(o为清凉住房)
12345678
xoxoxoxx 第一种情况
xoxoxxox 第二种情况
xoxxoxox 第三种情况
xxoxoxox 第四种情况
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll b[200005],a[200005];
int main()
{
ll t;
cin>>t;
while(t--)
{
ll n;
cin>>n;
for(int i=0;i<n;i++)
cin>>b[i];
for(int i=1;i<n-1;i++)
{
ll m;
m=max(b[i-1],b[i+1]);
b[i]>m?a[i]=0:a[i]=m-b[i]+1;
}
if(n&1)//为奇数
{
ll ans=0;
for(int i=1;i<n-1;i+=2)
ans+=a[i];
cout<<ans<<'\n';
continue;
}
ll res=0;
for(int i=1;i<n-1;i+=2)
res+=a[i];//第一种情况
ll ans=res;
for(int i=n-2;i>0;i-=2)
{
res-=a[i-1];
res+=a[i];//后三种情况逐一产生
ans=min(ans,res);//四种情况的比较
}
cout<<ans<<'\n';
}
}