eg:除了C題沒看懂和I題看不懂之外,都是中文題就不寫題意了。
比賽傳送門
A-操作序列
題解:map應用大賞,本以爲要開unordered_map,後來發現隨便寫寫就過了。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
map<int,int>mmap;
map<int,int>::iterator it;
int n;
int main(){
scanf("%d",&n);
while(n--){
int t,c;char ch;
scanf("%d%c",&t,&ch);
if(t==-1){
if(mmap.empty())puts("skipped");
else{
printf("%d\n",mmap.begin()->second);
mmap.erase(mmap.begin());
}
}else{
if(ch==' '){
scanf("%d",&c);
it=mmap.lower_bound(t-30);
if(it==mmap.end() || it->first>t+30)mmap[t]+=c;
}else{
if(mmap.count(t))printf("%d\n",mmap[t]);
else puts("0");
}
}
}
return 0;
}
B-樹上子鏈
題解:算是樹上dp吧,用dfs求出每個根的最大兩個兒子,答案就是。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const ll INF=1e12;
const double eps=1e-6;
using namespace std;
int n;
ll a[maxn],ans=-INF;
vector<int>G[maxn];
ll dfs(int x,int fa){
ll sum=0,cnt=0,num=0;
for(int i=0;i<G[x].size();i++){
int u=G[x][i];
if(u==fa)continue;
num=dfs(u,x);
if(num>sum)cnt=sum,sum=num;
else if(num>cnt)cnt=num;
}
ans=max(ans,a[x]+sum+cnt);
return max(0ll,a[x]+sum);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,-1);
printf("%lld\n",ans);
return 0;
}
D-收集紙片
題解:看到n的範圍很小,考慮暴力,直接枚舉全排列複雜度爲完全可以接受。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const ll INF=1e9;
const double eps=1e-6;
using namespace std;
int n,m,stx,sty;
int k,x[20],y[20],a[11];
//next_permutation(a,a+n)
int cal(int a,int b,int c,int d){
return abs(a-c)+abs(b-d);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
scanf("%d%d",&stx,&sty);
int ans=INF;
scanf("%d",&k);
for(int i=1;i<=k;i++)scanf("%d%d",&x[i],&y[i]);
for(int i=0;i<k;i++)a[i]=i+1;
int flag=1;
while(flag){
int nx=stx,ny=sty,tmp=0;
for(int i=0;i<k;i++){
tmp+=cal(nx,ny,x[a[i]],y[a[i]]);
nx=x[a[i]],ny=y[a[i]];
}
tmp+=cal(nx,ny,stx,sty);
ans=min(ans,tmp);
flag=next_permutation(a, a+k);
}
printf("The shortest path has length %d\n",ans);
}
return 0;
}
E-方塊塗色
題解:簽到題,答案爲。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
int n,m,r,c;
int main(){
while(~scanf("%d%d%d%d",&n,&m,&r,&c)){
printf("%lld\n",1ll*(n-r)*(m-c));
}
return 0;
}
F-累乘數字
題解:簽到題
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
int n,m,r,c;
int main(){
while(~scanf("%d%d",&n,&m)){
printf("%d",n);
for(int i=1;i<=m;i++)printf("00");
printf("\n");
}
return 0;
}
G-倉庫選址
題解:感覺巨難的一道題目(至今爲止沒有理解正解),四方暴力過了,牛客的評測機太猛了。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const ll INF=1e12;
const double eps=1e-6;
using namespace std;
int n,m;
int a[110][110];
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);
ll ans=INF;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++){
ll tmp=0;
for(int k=1;k<=m;k++)
for(int l=1;l<=n;l++)
tmp+=1ll*(abs(i-k)+abs(j-l))*a[k][l];
ans=min(ans,tmp);
}
printf("%lld\n",ans);
}
return 0;
}
H-貨物種類
題解:差分數組的思想,對於每一個倉庫i,開一個對應的Add數組和Del數組。對於每組讀入,Add[l]推入d物品,Del[r+1]推入d物品。之後進行一次掃描,即可獲得答案。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
map<int,int>mmap;
int n,m;
vector<int>L[maxn];
vector<int>R[maxn];
int main(){
scanf("%d%d",&n,&m);
while(m--){
int l,r,d;
scanf("%d%d%d",&l,&r,&d);
L[l].push_back(d);
R[r+1].push_back(d);
}
int cnt=0,ans=0,pos=0;
for(int i=1;i<=n;i++){
for(int j=0;j<L[i].size();j++){
int x=L[i][j];
if(mmap[x]==0)cnt++;
mmap[x]++;
}
for(int j=0;j<R[i].size();j++){
int x=R[i][j];
if(mmap[x]==1)cnt--;
mmap[x]--;
}
if(cnt>ans)ans=cnt,pos=i;
}
printf("%d\n",pos);
return 0;
}
J-計算a+b
題解:高精度加法,簽到題
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
using namespace std;
char s[maxn];
string v,ans,a;
string add(string a,string b){
v.clear();
int tmp=0,t=0;
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
while(a.size()!=b.size()){
if(a.size()>b.size())b.push_back('0');
else a.push_back('0');
}
for(int i=0;i<a.size();i++){
tmp=a[i]+b[i]-'0'*2+t;
t=tmp/10;
v.push_back(tmp%10+'0');
}
if(t>0)v.push_back(t+'0');
reverse(v.begin(),v.end());
return v;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
ans.clear();a.clear();
scanf("%s",&s);
int len=strlen(s),flag=1,cnt=0,pos=0;
for(int i=0;i<len;i++){
if(s[i]=='+')cnt++,pos=i;
else if(s[i]>='0' && s[i]<='9')continue;
else flag=0;
}
if(cnt==0 || cnt>1)flag=0;
if(pos==0 || pos==len-1)flag=0;
if(!flag)puts("skipped");
else {
for(int i=0;i<pos;i++)a.push_back(s[i]);
for(int i=pos+1;i<len;i++)ans.push_back(s[i]);
ans=add(ans,a);
cout<<ans<<endl;
}
}
return 0;
}