A
solution:
模拟题
按照题意模拟即可
std:
#include <bits/stdc++.h> using namespace std; #define ll long long string s; map<ll , ll > mp; set<int> se; set<int>::iterator it; int main() { int t; cin>>t; getchar(); while(t--) { int flag = 0,sign = 0,flag2 = 0; int cnt = 0; getline(cin,s); int len = s.length(); if(s[0] == '-'){ if(se.size() == 0){ printf("skipped\n"); }else{ it = se.begin(); cout<<mp[*it]<<endl; mp[*it] = 0; se.erase(*it); } continue ; } for(int i=len-1;i>=0;i--){ if(s[i] == ' '){ flag = 1; } } if(flag == 0){ int x = 0; for(int i=0;i<len;i++){ x = x*10 + (s[i]-'0'); } printf("%lld\n",mp[x]); continue ; } int x = 0,y = 0; for(int i=0;i<len;i++){ if(s[i] == ' '){ sign = 1; continue ; } if(sign == 0){ x = x*10 + (s[i]-'0'); }else{ y = y*10 + (s[i]-'0'); } } for(int i=max(0,x-30);i<=x+30;i++){ if(mp[i] != 0){ flag2 = 1; break ; } } if(flag2 == 1){ continue ; } mp[x] += y; se.insert(x); } return 0; }
B
solution:
简单的树上dp
树上dfs,记得初始化ans = -inf,没初始化为负数wa一发
std:
#include <bits/stdc++.h> using namespace std; #define ll long long const int maxn = 100005; int n,x,y; ll ans=-1e18,dp[maxn],a[maxn]; vector<int> v[maxn]; void dfs(int x,int fa) { dp[x] = a[x]; ans = max(ans , dp[x]); for(int i=0;i<v[x].size();i++){ int nex = v[x][i]; if(nex == fa) continue ; dfs(nex , x); ans = max(ans , dp[x] + dp[nex]); dp[x] = max(dp[x] , dp[nex] + a[x]); } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); dp[i] = -1e18; } for(int i=1;i<n;i++){ scanf("%d %d",&x,&y); v[x].push_back(y); v[y].push_back(x); } dfs(1,0); printf("%lld\n",ans); return 0; }
C
solution:
DFS
长度为12的字符串,考虑枚举可以更换的情况,直到无法更换,记录最大值即可
std:
#include <bits/stdc++.h> using namespace std; #define ll long long char s[20]; int ans = 12; void dfs() { for(int i=3;i<=12;i++){ if(s[i-2] == '-' && s[i-1] == 'o' && s[i] == 'o'){ s[i-2] = 'o',s[i-1] = '-',s[i] = '-'; dfs(); s[i-2] = '-',s[i-1] = 'o',s[i] = 'o'; } if(s[i-2] == 'o' && s[i-1] == 'o' && s[i] == '-'){ s[i-2] = '-',s[i-1] = '-',s[i] = 'o'; dfs(); s[i-2] = 'o',s[i-1] = 'o',s[i] = '-'; } } int sum = 0; for(int i=1;i<=12;i++){ if(s[i] == 'o') sum++; } ans = min(ans , sum); } int main() { int t; scanf("%d",&t); while(t--) { ans = 12; scanf("%s",s+1); dfs(); printf("%d\n",ans); } return 0; }
D
solution:
暴力枚举
一开始没考虑时间复杂度写的dfs超时了,改成next_permutation全排列就过了
std:
#include <bits/stdc++.h> using namespace std; #define ll long long const int maxn = 13; int a[maxn],b[maxn],c[maxn]; int main() { int t; scanf("%d",&t); while(t--) { int x,y,n,ans = 1e9; scanf("%d %d",&x,&y); scanf("%d %d",&a[0],&b[0]); scanf("%d",&n); for(int i=1;i<=n;i++){ c[i] = i; scanf("%d %d",&a[i],&b[i]); } c[0] = 0; do{ int cnt = 0; for(int i=1;i<=n;i++){ cnt += abs(a[c[i]] - a[c[i-1]]) + abs(b[c[i]] - b[c[i-1]]); } cnt += abs(a[c[0]] - a[c[n]]) + abs(b[c[0]] - b[c[n]]); ans = min(ans ,cnt); }while(next_permutation(c,c+1+n)); printf("The shortest path has length %d\n",ans); } return 0; }
E
solution:
签到题,输出n×m + r×m + (n - r)×c
std:
#include <bits/stdc++.h> using namespace std; #define ll long long int main() { ll n , m, r,c; while(cin>>n>>m>>r>>c) { ll cnt1 = n*m; ll cnt2 = r*m + (n - r)*c; cout<<cnt1 - cnt2<<endl; } return 0; }
F
solution:
签到题
乘几次就加几个00
std:
#include <bits/stdc++.h> using namespace std; #define ll long long int main() { ll n ,d; while(cin>>n>>d){ cout<<n; for(int i=1;i<=d;i++){ cout<<"00"; } cout<<endl; } return 0; }
G
solution:
不明白这个题要干什么。。。n的四次方都过,假的吧
std:
#include <bits/stdc++.h> using namespace std; #define ll long long int a[105][105]; int main() { int t; scanf("%d",&t); while(t--) { int n,m,ans = 1e9+10; scanf("%d %d",&m,&n); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&a[i][j]); } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ int cnt = 0; for(int k=1;k<=n;k++){ for(int z=1;z<=m;z++){ cnt += (a[k][z]*(abs(k-i) + abs(z-j))); } } ans = min(ans , cnt); } } printf("%d\n",ans); } return 0; }
H
solution:
差分数组/线段树
差分数组的做法挺简单的,就是只需要最后一次查询,我们可以从前往后遍历,维护当前位置一共存放了多少种不同的货物,类似前缀和
std:
#include <bits/stdc++.h> using namespace std; #define ll long long const int maxn = 100005; vector<int> add[maxn],del[maxn]; map<int , int > mp; int main() { int n,m,x,y,z; scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d %d %d",&x,&y,&z); add[x].push_back(z); del[y+1].push_back(z); } int ans = 0,sum = 0,maxx = 0; for(int i=1;i<=n;i++){ for(int j=0;j<add[i].size();j++){ mp[add[i][j]]++; if(mp[add[i][j]] == 1) sum++; } for(int j=0;j<del[i].size();j++){ mp[del[i][j]]--; if(mp[del[i][j]] == 0) sum--; } if(sum > maxx){ maxx = sum; ans = i; } } printf("%d\n",ans); return 0; }
I
no solution,计算几何待补。。。
J
solution:
签到题
首先判断是不是a+b的类型,然后用大数相加即可,比赛因题面描述不清,前导0的样例已经移除了,这。。。
std:
#include <bits/stdc++.h> using namespace std; #define ll long long string sum(string s1,string s2) { if(s1.length()<s2.length()) { string temp=s1; s1=s2; s2=temp; } for(int i=s1.length()-1,j=s2.length ()-1;i>=0;i--,j--) { s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0)); if(s1[i]-'0'>=10) { s1[i]=char((s1[i]-'0')%10+'0'); if(i) s1[i-1]++; else s1='1'+s1; } } return s1; } int main() { int t; cin>>t; while(t--) { string s; cin>>s; string s1,s2; int flag = 0; for(int i=0;i<s.length();i++){ if(s[i] == '+'){ flag = 1; continue ; } if(s[i] >= '0' && s[i] <= '9'){ if(flag == 0){ s1 = s1 + s[i]; }else{ s2 = s2 + s[i]; } continue ; } flag = 2; } if(s1.length() == 0 || s2.length() == 0 || flag == 2){ cout<<"skipped"<<endl; continue ; } string ans = sum(s1,s2); cout<<ans<<endl; } return 0; }