A——Primary Task
字符串读入按照题目要求判断一下就OK
#include<bits/stdc++.h>
using namespace std;
void solve()
{
string s;
cin>>s;
if(s.size()<=2)
{
cout<<"No\n";
return;
}
if(s[0]!='1'||s[1]!='0')
{
cout<<"No\n";
return;
}
if(s.size()==3)
{
if(s[2]>='2') cout<<"Yes\n";
else cout<<"No\n";
return;
}
if(s.size()>3)
{
if(s[2]=='0') cout<<"No\n";
else cout<<"Yes\n";
}
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
B——Seating in a Bus
用p数组记录一下1-n的乘客分别坐哪里,用st数组记录一下当前哪些位置有人坐,1-n的遍历一下p数组,除了第一次以外,每次判断一下 s t [ p [ i ] + 1 ] st[p[i]+1] st[p[i]+1] 或者 s t [ p [ i ] − 1 ] st[p[i]-1] st[p[i]−1] 是否有人坐,没有人坐则返回No
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int st[N],p[N];
void solve()
{
int n;
cin>>n;
for(int i=0;i<=n+1;i++) st[i]=0;
for(int i=1;i<=n;i++)
cin>>p[i];
for(int i=1;i<=n;i++)
{
if(i==1)
{
st[p[i]]=1;
continue;
}
if(st[p[i]+1]==1||st[p[i]-1]==1) st[p[i]]=1;
else
{
cout<<"No\n";
return;
}
}
cout<<"Yes\n";
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
C——Numeric String Template
需要保证每个数字对应一个字母,每个字母对应一个数字,开两个Map存一下对应关系,如果没有冲突就输出Yes,否则输出No。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll a[N];
void solve()
{
ll n,q;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cin>>q;
while(q--)
{
int flg=1;
map<char,ll> M1;
map<ll,char> M2;
string s;
cin>>s;
if(s.size()!=n)
{
cout<<"No\n";
continue;
}
for(int i=0;i<s.size();i++)
{
if(M1.count(s[i])==0&&M2.count(a[i+1])==0)
{
M1[s[i]]=a[i+1];
M2[a[i+1]]=s[i];
}
else if(M1.count(s[i])!=0&&M2.count(a[i+1])!=0)
{
if(M1[s[i]]!=a[i+1]||M2[a[i+1]]!=s[i])
{
flg=0;
break;
}
}
else
{
flg=0;
break;
}
}
if(flg) cout<<"Yes\n";
else cout<<"No\n";
}
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}
D——Right Left Wrong
为了使分数尽可能的多,就要尽可能的把每个数多加几次,分析可知首先先找到最中间的一对 L R LR LR,然后向右找 R R R,向左找 L L L,每找到一对 L R LR LR, a n s ans ans 就加上 h [ d R ] − h [ d L − 1 ] h[d_R]-h[d_L-1] h[dR]−h[dL−1]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=2e5+10;
int p[N];
ll h[N];
char s[N];
int n;
ll check(int l,int r)
{
ll ans=0;
int dl=-1,dr=-1;
for(int i=l+1;i<=r-1;i++)
{
if(s[i]=='L'&&dl==-1)
{
dl=i;
break;
}
}
for(int i=r-1;i>=l+1;i--)
{
if(s[i]=='R'&&dr==-1)
{
dr=i;
break;
}
}
// cout<<dl<<' '<<dr<<'\n';
if(dl!=-1&&dr!=-1&&dr-dl>=1)
{
// cout<<"!";
ans=check(dl,dr);
}
ans+=h[r]-h[l-1];
return ans;
}
void solve()
{
int l=-1,r=-1;
ll ans=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>p[i];
h[i]=h[i-1]+p[i];
}
cin>>s+1;
for(int i=1;i<=n;i++)
{
if(s[i]=='L'&&l==-1) l=i;
if(s[i]=='R') r=i;
}
if(l!=-1&&r!=-1)
{
if(r-l>2) ans=check(l,r);
else ans=h[r]-h[l-1];
cout<<ans<<'\n';
}
else cout<<0<<'\n';
}
int main()
{
ios
int t;
cin>>t;
while(t--)solve();
return 0;
}
E——Photoshoot for Gorillas
纯暴力,首先统计一下第一行和第一列中的每个格子可以在出现在几个
k
∗
k
k*k
k∗k的矩形中
第一行第
i
i
i 列
v
h
[
i
]
=
m
i
n
(
m
i
n
(
i
,
n
−
i
+
1
)
,
m
i
n
(
n
−
k
+
1
,
k
)
)
v_h[i]=min(min(i,n-i+1),min(n-k+1,k))
vh[i]=min(min(i,n−i+1),min(n−k+1,k))
第一列第
i
i
i 行
v
w
[
i
]
=
m
i
n
(
m
i
n
(
i
,
m
−
i
+
1
)
,
m
i
n
(
m
−
k
+
1
,
k
)
)
v_w[i]=min(min(i,m-i+1),min(m-k+1,k))
vw[i]=min(min(i,m−i+1),min(m−k+1,k))
然后遍历每个格子
n
u
m
[
i
]
[
j
]
=
v
h
[
i
]
∗
v
w
[
j
]
num[i][j]=v_h[i]*v_w[j]
num[i][j]=vh[i]∗vw[j],将所得的数存入数组
a
a
a 中从大到小排序
将
W
W
W 个大猩猩的身高存入数组
b
b
b 中从大到小排序,然后每次取
a
a
a 数组的最大乘上
b
b
b 数组的最大求和,直到
b
b
b 数组为空,
1. #include<bits/stdc++.h>
1. using namespace std;
1. typedef long long ll;
1.
1. void solve()
1. {
1. int n,m,W,k;
1. cin>>n>>m>>k;
1. vector<ll> w,v;
1. vector<ll> v_h(n+1),v_w(m+1);
1. for(int i=1;i<=n;i++)
1. v_h[i]=min(min(i,n-i+1),min(n-k+1,k));
1. for(int i=1;i<=m;i++)
1. v_w[i]=min(min(i,m-i+1),min(m-k+1,k));
1.
1. // for(int i=1;i<=n;i++)
1. // cout<<v_h[i]<<' ';
1. // for(int i=1;i<=m;i++)
1. // cout<<v_w[i]<<' ';
1. for(int i=1;i<=n;i++)
1. {
1. for(int j=1;j<=m;j++)
1. {
1. // cout<<v_h[i]*v_w[j]<<" ";
1. w.push_back(v_h[i]*v_w[j]);
1. }
1. // cout<<'\n';
1. }
1. sort(w.begin(),w.end());
1. // for(int i=0;i<w.size();i++) cout<<w[i]<<' ';
1. // cout<<'\n';
1. cin>>W;
1. for(int i=1;i<=W;i++)
1. {
1. int x;
1. cin>>x;
1. v.push_back(x);
1. }
1. sort(v.begin(),v.end());
1. // for(int i=0;i<v.size();i++) cout<<v[i]<<' ';
1. ll ans=0;
1. for(int i=v.size()-1,j=w.size()-1;i>=0;i--,j--)
1. {
1. ans+=(ll)v[i]*w[j];
1. }
1. cout<<ans<<'\n';
1.
1. }
F——Color Rows and Columns
简单的分组背包问题, v [ i ] [ j ] v[i][j] v[i][j] 表示第 i i i 个物品获得 j j j 个点数所需的点数(有点废话,其实不需要这个,写在这里只是为了与分组背包模板对应,我是蒟蒻 -_-悲.jpg), w [ i ] [ j ] w[i][j] w[i][j] 表示表示第 i i i 个物品获得 j j j 个点数所需操作的次数,重点就是处理 w [ i ] [ j ] w[i][j] w[i][j],贪心处理就行,对于每个矩形来说每次获得一个点数所需的操作数 n u m = m i n ( l , w ) num=min(l,w) num=min(l,w),然后 m a x ( l , w ) − 1 max(l,w)-1 max(l,w)−1就行,这样贪心 ( l + w ) (l+w) (l+w) 次就 o k ok ok 了
/* /\_/\
* (= ._.)
* / > \>
*/
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;
int v[1010][210],w[1010][210],s[1010];
int f[1010];
void solve()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
f[i]=inf;
}
for(int i=1;i<=n;i++)
{
int a,b,cnt=0;
cin>>a>>b;
s[i]=a+b;
if(a>b) swap(a,b);
while(a&&b)
{
++cnt;
v[i][cnt]=cnt;
w[i][cnt]=w[i][cnt-1]+a;
// cout<<w[i][cnt]<<'\n';
b--;
if(a>b) swap(a,b);
}
++cnt;
v[i][cnt]=cnt;
w[i][cnt]=w[i][cnt-1];
}
f[0]=0;
for(int i=1;i<=n;i++)
{
for(int j=m;j>=0;j--)
{
for(int k=0;k<=s[i];k++)
if(j>=v[i][k])
{
f[j]=min(f[j],f[j-v[i][k]]+w[i][k]);
}
}
// cout<<'\n';
}
// for(int i=1;i<=m;i++)
if(f[m]>inf/2)cout<<"-1\n";
else cout<<f[m]<<'\n';
}
int main()
{
int t;
cin>>t;
while(t--) solve();
return 0;
}