A. Got Any Grapes?
水题
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxn=1e5+9;
int main(){
int i,j,k,x,y,z,_g,_b,_p;
cin>>x>>y>>z;
cin>>_g>>_p>>_b;
if(_g>=x){
_g-=x;
if(_g+_p>=y){
if(_g+_p+_b-y>=z){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
else{
cout<<"NO"<<endl;
}
}
else{
cout<<"NO"<<endl;
}
}
B. Yet Another Array Partitioning Task
从大到小找m*k个数,并且记录每个数出现的次数,然后扫一遍序列,当出现了这m*k的数中的m个时,咱就储存一下位置,然后重新计数。
代码:
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const ll maxn=2e5+9;
ll a[maxn],b[maxn],ans[maxn];
bool cmp(int a,ll b){
return a>b;
}
map<long long ,ll>mp;
int main(){
ll i,j,k,n,m;
cin>>n>>m>>k;
for(i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+n+1,cmp);
long long sum=0;
for(i=1;i<=m*k;i++){
// cout<<b[i]<<endl;
mp[b[i]]++;
sum+=b[i];
}
ll t=0,cnt=1,_num=0;
for(i=1;i<=n;i++){
if(cnt!=k){
if(mp[a[i]]!=0){
_num++;
mp[a[i]]--;
}
if(_num==m){
cnt++;
ans[t++]=i;
_num=0;
}
}
}
//cout<<cnt<<endl;
cout<<sum<<endl;
for(i=0;i<t;i++){
cout<<ans[i]<<' ';
}
}
C. Trailing Loves (or L'oeufs?)
我们假设b恒等于10,那么我们找末尾有几个0,其实就可以通过找2和5的个数来算出末尾0的个数,也就是找质因子的个数,那么把b换成其他的数也是类似的,相当于就是找x的质因子的个数。
代码:
我的代码稍微复杂化了一点,其实根本不用求素数。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const long long maxn=1e7+9;
ll vis[maxn];
ll pri[maxn],ct=0;
void prime(){
ll cnt=0,i,j;
for(ll i=2;i<=maxn;i++){
if(!vis[i]){
vis[i]=1;
pri[ct++]=i;
for(ll j=i*i;j<=maxn;j+=i){
vis[j]=1;
}
}
}
}
map<ll,ll>mp;
map<ll, ll> _cnt;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
ll i,j,k,n,m;
prime();
cin>>n>>m;
vector<ll>_yz;
for(i=0;i<ct;i++){
if(m%pri[i]==0){
ll sum=0;
while(m%pri[i]==0){
sum++;
m/=pri[i];
}
_yz.push_back(pri[i]);
mp[pri[i]]=sum;
}
}
if(m!=1)_yz.push_back(m),mp[m]=1;;
// for(auto it:_yz)cout<<it<<"sfsaf"<<endl;
for(i=0;i<_yz.size();i++){
ll u=n;
while(u){
_cnt[_yz[i]]+=u/_yz[i];
u/=_yz[i];
}
}
ll ans=1e18;
for(i=0;i<_yz.size();i++){
ll sum=inf;
if(mp[_yz[i]]!=0)
sum=_cnt[_yz[i]]/mp[_yz[i]];
ans=min(ans,sum);
}
cout<<ans<<endl;
}
D. Flood Fill
区间DP,对于每一个区间,有两个选择,要么区间全变为区间最左边的那个颜色,要么变成最右边的那个颜色
那么得到一个状态转移方程式
dp[i][j][0]=min(dp[i+1][j][0]+(a[i]!=a[i+1]),dp[i+1][j][1]+(a[i]!=a[j]));
dp[i][j][1]=min(dp[i][j-1][1]+(a[j]!=a[j-1]),dp[i][j-1][0]+(a[i]!=a[j]));
代码:
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=5e3+9;
int dp[maxn][maxn][2],a[maxn];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int i,j,k,n;
cin>>n;
for(i=1;i<=n;i++){
cin>>a[i];
}
for(int len=2;len<=n;len++){
for(i=1;i<=n-len+1;i++){
int ends=i+len-1;
dp[i][ends][0]=min(dp[i+1][ends][0]+(a[i]!=a[i+1] ),dp[i+1][ends][1]+(a[i]!=a[ends]) );
dp[i][ends][1]=min(dp[i][ends-1][1]+(a[ends-1]!=a[ends]),dp[i][ends-1][0]+(a[ends]!=a[i]));
}
}
cout<<min(dp[1][n][0],dp[1][n][1])<<endl;
}