A
直接模擬即可。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000100,mod=998244353;
int a[N];
signed main(){
string s,t;
cin>>s>>t;
if(s=="AtCoder"&&t=="Land")cout<<"Yes\n";
else cout<<"No\n";
}
B
直接模擬即可。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000100,mod=998244353;
int a[N];
signed main(){
int n,t;
cin>>n>>t;
for(int i=1;i<=n;i++)cin>>a[i];
int now=-1e18;
for(int i=1;i<=n;i++){
int xu=now;
if(xu<=a[i])now=a[i]+t;
else now=xu+t;
cout<<now<<'\n';
}
}
C
發現 \(n\) 很小,所以直接暴力列舉每一個狀態,並判斷這個狀態是否可以覆蓋所有的爆米花。如果可以覆蓋那麼當前狀態的位數就是當前所用的攤位的數量。取最小值即可。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000100,mod=998244353;
char s[3010][3010];
signed main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)scanf("%s",s[i]);
int cost=233;
for(int i=1;i<(1ll<<n);i++){
set<int>se;
for(int j=0;j<n;j++)if(i>>j&1)
for(int k=0;k<m;k++)if(s[j][k]=='o')
se.insert(k);
if(se.size()==m)cost=min(cost,(int)__builtin_popcountll(i));
}
cout<<cost<<'\n';
}
D
對於每一個人 \(i\),使用 multiset
找到讓她可以滿足的,價值最小的禮物分配給她。時間複雜度為 \(O(n\log n)\)。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000100,mod=998244353;
int a[N],b[N];
signed main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++)cin>>b[i];
multiset<int>se;
int res=0;
for(int i=1;i<=n;i++)se.insert(a[i]);
sort(a+1,a+n+1,greater<>());
for(int i=1;i<=m;i++){
auto it=se.lower_bound(b[i]);
// cout<<"dbg "<<i<<' '<<b[i]<<'\n';
if(it==se.end()){
res=-1;
break;
}
res+=*it;
se.erase(it);
}
cout<<res<<'\n';
}
G
實際上 CF57E 也有一個(有點)類似的結論。
容易發現 \(n\times m\) 步之後一定可以到達任意的一個結點。因此 \(n\times m\) 步之後一定是停在某一個結點攢貢獻。所以設 \(f_{i,j,k}\) 表示當前走了 \(i\) 步,目前位於結點 \((j,k)\) 的最大收益。很顯然每一個 \(f_{i,j,k}\) 都可以從 \((j,k)\) 結點本身和 \((j,k)\) 結點四連通的結點轉移而來。
此時若 \(k\le n\times m\) 則答案已經求出,\(k>n\times m\) 則列舉最後到達的每一個結點 \((i,j)\),這個結點的最大貢獻就是 \(f_{n\times m,i,j}+(n\times m-k)\times a_{i,j}\)。可能這個貢獻並不一定是最大貢獻,但是最大貢獻一定可以透過這種方式得到。
時間複雜度為 \(O(n^2m^2)\)。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000100,mod=998244353;
int a[55][55],f[55*55][55][55];
//設f[i][j][k]表示現在是第i個操作, 當前位於(j,k)
signed main(){
int n,m,k;
cin>>n>>m>>k;
int si,sj;
cin>>si>>sj;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
memset(f,-0x3f,sizeof f);
f[0][si][sj]=0;
for(int i=1;i<=min(n*m,k);i++){
for(int j=1;j<=n;j++)
for(int k=1;k<=m;k++)
f[i][j][k]=f[i-1][j][k]+a[j][k];
for(int j=1;j<=n;j++)
for(int k=1;k<=m;k++){
const int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
for(int d=0;d<4;d++){
int x=j+dx[d],y=k+dy[d];
if(x>=1&&x<=n&&y>=1&&y<=m)
f[i][x][y]=max(f[i][x][y],f[i-1][j][k]+a[x][y]);
}
}
}
if(k<=n*m){
int res=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
res=max(res,f[k][i][j]);
cout<<res<<'\n';
}else{
int res=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
int now=f[n*m][i][j]+(k-n*m)*a[i][j];
res=max(res,now);
}
cout<<res<<'\n';
}
}